Skip to content

Instantly share code, notes, and snippets.

@astyfx
Last active January 27, 2016 03:00
Show Gist options
  • Save astyfx/ae04f8426a0a5426eb18 to your computer and use it in GitHub Desktop.
Save astyfx/ae04f8426a0a5426eb18 to your computer and use it in GitHub Desktop.

Python 내용 정리

  • “%r” % anything

    • 무엇이든가에 출력하라 ( formatting string)
    • RAW data를 그대로 출력한다(디버깅에 용의)
    • representation → repr
  • argv

    • argument variable
  • Magic Method

    • class TestClass(object): def getattr(self, k): print "log: getattr" print k return k

      test_class = TestClass()

      print test_class.Test("HI")

      __getattr__을 통해 존재하지 않는 메소드에 대한 콜을 받을 수 있다(스트링으로)

      http://www.rafekettler.com/magicmethods.html

  • 연산기호

    • <> : 다르다 (!=)
  • Performance Tips

  • Inheritance VS Composition

    • ex) Composition

    • class Other(object): def override(self): print "OVERRIDE"

      class Child(object): def init(self): self.other = Other()

  • try-except

    • 모듈이 일으키는 예외를 처리할 때만 써라?
  • Decorator

    • 기본형태
      • def check_is_admin(f): def wrapper(*args, **kwargs): if kwargs.get('username') != 'admin': raise Exception('This user is not allowed to access') return f(*args, **kwargs) return wrapper

        @check_is_admin

    • 결점
      • 위의 형태로 할경우 docstring(__doc__), name(__name__) 같은 속성이 없다.
      • functools.update_wrapper 함수를 사용하여 원래 함수의 속성들을 래퍼로 복사한다.
      • 이 기능을 functools는 데코레이터로 제공한다.
        • @functools.wraps(f)
      • inspect 모듈
        • 함수의 시그너처를 얻어 낼 수 있다.

        • import functools import inspect

          def check_is_admin(f): @functools.wraps(f) def wrapper(*args, **kwargs): func_Args = inspect.getcallargs(f, *args, **kwargs) if func_args.get('username') != 'admin': raise Exception("This user is not allowed to access.") return f(*args, **kwargs) return wrapper

  • Method

    • 파이썬에서 메서드는 어떻게 작동하는가
    • 메서드는 클래스의 속성(attribute)으로 저장되는 함수다.
      • 기본적으로 클래스에 정의하는 메서드는 unbound(2.x)
      • __self__를 통해 클래스의 인스턴스를 생성하여 self에 인자 값을 넘겨 줄 수 있는 상태 인지 확인 할 수 있다.
    • 정적메서드
      • 클래스에 속한 메서드지만 위처럼 바운드 여부에 상관없이, 즉 클래스 인스턴스를 사용하지 않는 메서드이다.
      • @staticmethod
        • argument에서 self 인자를 제외 할 수 있다.
        • 객체를 생성 할 때 바운드 메서드를 매번 인스턴스화할 필요가 없다. 바운드 메서드 역시 객체이므로 객체를 만드는 비용이 발생한다.
    • 클래스메서드
      • @classmethod
        • 인스턴스가 아닌 클래스에 바운드되는 메서드
        • @classmethod def get_radius(cls): return cls.radius
        • 흔히 객체를 특정 방법으로 만드는 팩토리 메서드를 만드는 데 사용한다.
        • __init__과 비슷한 형태로 원하는 데이터를 가진상태로 인스턴스를 생성(Factory)하는데 용의하다.
    • 추상메서드
      • 상위 클래스에 정의되었지만 실제 메서드 구현이 있을 수도 있고 없을 수도 있는 메서드다.
        • @staticmethod def get_radius(): raise NotImplementedError
      • abc 모듈
        • import abc

        • import abc

          class BestPizza(Pizza): metaclass = abc.ABCMeta

          @abc.abstractmethod
          def get_ingredients(self):
            """return ingredients"""
          
      • 파이썬에서는 다른 언어와 달리 추상 메서드에 구현 코드를 포함시켜도 된다. super로 접근도 가능하다.
    • super
      • 파이썬은 아주 초기 시절부터 다중 상속이 가능했다.
      • mro()
        • Method resolution order, MRO
      • Descriptor Protocol
        • @property
  • generator

    • cf) lambda 옆에는 expression이 온다.
    • yield는 표현식
      • yield 표현식(yield expression)의 값은 None
    • caller 가 제너레이터로 값을 전달해 준다면 yield 표현식은 None 이외의 값을 가질 수 있다. 이를 위해 제너레이터에는 send() 라는 메서드가 제공된다.
    • next(g)g.send(None)
    • 제너레이터에는 send() 외에도 throw()close() 라는 메서드가 더 제공된다. 제너레이터에 이런 기능들이 들어간 목적은 코루틴(coroutine) 때문이다.
    • Subroutine
      • 일반적인 함수의 형태로 코드의 순서대로 내려오다 return을 만나면 종료되는 형태
    • GIL을 조금 찾아보시면 아시겠지만 CPU-bound 작업에는 프로세스를 스폰하는 방법이 무조건 유리
  • list comprehension

  • 함수형 표준 함수

    • map(function, iterable)
      • function을 iterable의 각 아이템을 사용해 호출하고 2에서는 결과를 리스트로 3에서는 반복 가능한 map객체를 돌려준다.
    • filter(function or None, iterable)
      • iterable의 아이템을 function의 결과에 근거해 필터링하고 2에서는 리스트, 3에서는 반복 가능한 filter를 돌려준다.
    • enumerate(iterable[, start])
      • 반복 가능한 enumerate객체를 돌려주고, 이 객체는 튜플을 yield한다.
    • sorted(iterable, key=None, reverse=False)
      • 정렬된 iterable을 돌려준다. key 인자로 정렬에 사용할 함수를 넘길 수 있다.
    • any(iterable), all(iterable)은 모두 iterable의 값에 따라 boolean을 돌려준다.
      • 값들이 전부 또는 하나라도 조건을 충족하는지 검사할 때 유용
    • zip(iter1, [,iter2 […]])
      • 다수의 리스트를 받아서 튜플들로 결합
      • 키 목록과 값 목록을 dict로 바꿀 때 유용
    • 2버전 itertools.izip, itertools.imap, itertools.ifilter 등
    • functools.partial
      • 함수의 행위를 변경하는게 아니라 함수가 필요로 하는 인자를 변경하는 트릭으로 래퍼 함수를 만들 수 있게 해준다.
        • first([-1, 0, 1, 2], key=partial(greater_than, min=42))
  • AST(Abstract Syntax Tree) 추상 구문 트리

    • 모든 프로그래밍 언어는 소스 코드를 추상화한 구조를 트리로 표현
    • 파이썬도 소스 파일을 파싱하여 소스의 AST를 만든다.
  • 데이터구조

    • dict
      • .get()
    • set
      • 중첩되는 for문과 if 문이 필요할 때 set이 가진 기능들로 해결할 수 있는 경우가 많다.

      • def has_invalid_fields(fields): for field in fields: if field not in ['foo', 'bar']: return True return False

        def has_invalid_fields(fields): return bool(set(fields) - set(['foo', 'bar'])

    • collections.defaultdict
      • import collections

        def add_animal_in_family(species, animal, family): species[family].add(animal)

        species = collections.defaultdict(set) # species = {} add_animal_in_family(species, 'cat', 'felidea')

  • 프로파일링

    • cProfile
    • dis
      • def x(): return 42

        import dis dis.dis(x)

    • 함수 내에 함수를 정의해야 하는 유일한 경우는 클로저(Closure)를 만들 때
  • 정렬된 리스트와 bisect

    • 정렬된 리스트 O(log n)의 시간에 값을 가지고 올 수 있다.
    • bisection 알고리즘 → bisect 모듈
    • bisect.bisect(list, item) item의 인덱스를 돌려준다.
      • bisect.bisect, bisect.bisect_left, bisect.bisect_right
    • bisect.insort(list, item) 인덱스를 얻어오는 즉시 추가
      • bisect.insort, bisect.insort_left, bisect.insort_right
  • 네임드튜플과 슬롯

    • 파이썬 객체의 특징 중 하나는 모든 속성을 내부에 있는 어떤 딕셔너리에 저장하는 것
    • 파이썬의 클래스는 __slots__ 속성을 정의 할 수 있다. 클래스의 객체에서 허용하는 속성들을 열거 할 수 있다.
    • Named Tuple
      • Foobar = collections.namedtuple(‘Foobar’, [‘x’, ‘y’])
  • memoization

    • 메모이제이션은 결과를 캐싱하여 함수 호출 속도를 높여주는 기법
    • cache
  • 버퍼 프로토콜을 사용한 제로 카피

    • memoryview
    • bytearray
    • I/O함수에게 미리 메모리에 할당한 객체에 써달라고 요청하면 memoryview객체를 안써도 된다.
  • with

    • context manager
  • six

    • 2to3
  • 메타 클래스

    • #TODO
  • Long Text

  • Zen of python

  • class getattr, setattr

    • 파이썬 클래스에서 모델 attribute들을 돌면서 데이터를 변경할경우
    • setattr(model_instance, key, value) 로 변경 할 수 있다.
    • **plan ****= PricePlan.query.get(id) ****for key, ****value **in request.json.iteritems(): **** print setattr(plan, key, value)
  • Variable Reference

  • 강의 or tips

  • Best Practices

  • Pyenv

  • Filter

  • Advanced Design Patterns

  • Magic Method with __getattr__

  • class TestClass(object): def getattr(self, k): print "log: getattr" print k return k

    test_class = TestClass()

    print test_class.Test("HI")

    // __getattr__을 통해 존재하지 않는 메소드에 대한 콜을 받을 수 있다(스트링으로)

    // http://www.rafekettler.com/magicmethods.html

  • Reduce visual noise with variable positional arguments

  • def log(message, values): if not values: print(message) else: values_str = ', '.join(str(x) for x in values) print('%s: %s' % (message, values_str))

    log('My numbers are', [1, 2]) log('Hi there', [])

    My numbers are: 1, 2 Hi there

    def log(message, *values): # The only difference if not values: print(message) else: values_str = ', '.join(str(x) for x in values) print('%s: %s' % (message, values_str))

    log('My numbers are', 1, 2) log('Hi there') # Much better

    My numbers are: 1, 2 Hi there

    • Functions can accept a variable number of positional arguments by using *args in thedef statement.
    • You can use the items from a sequence as the positional arguments for a function with the * operator.
    • Using the * operator with a generator may cause your program to run out of memory and crash.
    • Adding new positional parameters to functions that accept *args can introduce hard-to-find bugs.
  • Argument Related

  • Use None and Docstring to specify dynamic default arguments

    • def log(message, when=None): """Log a message with a timestamp.

        Args:
            message: Message to print.
            when: datetime of when the message occurred.
                Defaults to the present time.
        """
        when = datetime.now() if when is None else when
        print('%s: %s' % (when, message))
      
    • Default arguments are only evaluated once: during function definition at module load time. This can cause odd behaviors for dynamic values (like {} or []).

    • Use None as the default value for keyword arguments that have a dynamic value. Document the actual default behavior in the function’s docstring.

  • Python Logging

  • Python Subprocessing

  • Python Standard Docstring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment