Python/Syntax 2021. 8. 24. 14:01

고급 문법

열거 가능 객체 (iterable)

  • for 문의 순회 대상 객체이다.

  • __iter__() 메서드로 열거 가능 객체를 획득한다.

    • iter(호출가능한객체, 반복을끝낼값) 함수로 __iter__() 메서드를 호출할 수 있다.

    • 반복을 끝낼 값이 나오면 StopIteration 예외가 발생한다.

    • 만약 클래스를 직접 구현하고 멤버 변수에 리스트가 있는 상황에서, 그 리스트를 순회하려면 __iter__() 메서드의 반환 값에 iter(해당리스트) 이런 식으로 iter 함수를 이용해 반환하면 된다.

  • 매 루프마다 __next__() 메서드를 통해 다음 요소를 받는다.

    • 첫 요소도 이걸로 받는다.

    • next(반복가능한객체, 기본값) 함수로 __next__() 메서드를 호출할 수 있다.

      • 마지막 요소에서 __next__() 를 호출하는 경우에는 StopIteration 예외가 발생하고 반복문이 끝난다.

      • 만약 기본값을 설정하면 예외 대신 계속 기본값이 출력된다.

    • 이 예외는 for 문에서 내부적으로 처리한다.

    • 유사 기능 구현 예시

      nums = [11, 22, 33]
      
      it = iter(nums)
      while True:
          try:
              num = next(it)
          except StopIteration:
              break
          print(num)
      
      ''' stdout
      11
      22
      33
      '''
    • __iter__, __next__ 메서드 구현 예시

      class Seq:
          def __init__(self, data):
              self.data = data
              self.index = -2
      
          def __iter__(self):
              self.index = -2
              return self
      
          def __next__(self):
              self.index += 2
              if self.index >= len(self.data):
                  raise StopIteration
              return self.data[self.index:self.index + 2]
      
      solarterm = Seq("입춘우수경칩춘분청명곡우입하소만망종하지소서대서")
      for idx, k in enumerate(solarterm):
          if idx: 
              print(',', end=' ')
          print(k, end='')
      print()
      
      for idx, k in enumerate(solarterm):
          if idx: 
              print(',', end=' ')
          print(k, end='')
      print()
      
      print(', '.join(solarterm))
      
      ''' stdout
      입춘, 우수, 경칩, 춘분, 청명, 곡우, 입하, 소만, 망종, 하지, 소서, 대서
      입춘, 우수, 경칩, 춘분, 청명, 곡우, 입하, 소만, 망종, 하지, 소서, 대서
      입춘, 우수, 경칩, 춘분, 청명, 곡우, 입하, 소만, 망종, 하지, 소서, 대서
      '''

제너레이터 (Generator)

  • 함수에서 데이터를 연속해서 리턴한다. (yield)

  • 함수가 끝나거나 return을 실행하면 StopIteration 예외가 발생한다.

    def seqgen(data):
        for index in range(0, len(data), 2):
            yield data[index:index+2]
    
    solarterm = seqgen("입춘우수경칩춘분청명곡우입하소만망종하지소서대서")
    
    print(solarterm)
    print(dir(solarterm))
    
    for k in solarterm: 
        print(k, end = ',')
    
    print(','.join(solarterm)) # 출력 X
    
    ''' stdout
    입춘,우수,경칩,춘분,청명,곡우,입하,소만,망종,하지,소서,대서,
    '''
  • range, enumerate, filter, zip은 제너레이터이다.

  • 순차적으로 반환을 하기 때문에 메모리 효율 측면에서 좋다.


데코레이터(Decorator)

일급 객체 (first-class object, 일급 시민)

  • 다른 객체들에 일반적으로 적용 가능한 연산을 모두 지원하는 객체를 가리킨다.

    일급 객체와 이급 객체. ALGOL에서 실수는 표현식에 사용하거나 변수에 할당할 수 있으며, 프로시저에 매개변수로 넘겨질 수 있다. 하지만 프로시저의 경우 프로시저 콜에서 호출 대상 혹은 매개 변수로 등장할 수 있을 뿐이며, 프로시저를 반환하는 프로시저는 없다. 이런 측면에서 ALGOL에서의 프로시저는 이급 시민이다. 언제나 직접 나타나야 하며 변수나 연산식으로 대신 나타낼 수 없기 때문이다. (1960년대, 영국의 컴퓨터 과학자 크리스토퍼 스트래치)

  • 로빈 포플스톤의 정의

    1. 모든 요소는 함수의 실제 매개변수가 될 수 있다.
    2. 모든 요소는 함수의 반환 값이 될 수 있다.
    3. 모든 요소는 할당 명령문의 대상이 될 수 있다.
    4. 모든 요소는 동일 비교의 대상이 될 수 있다.

지역 함수

  • 함수 안에 정의된 함수이다.

    • 함수가 정의된 함수 내에서만 사용할 수 있다.

    • 함수의 이름 충돌 방지용으로 사용할 수 있다.

    • 함수를 리턴할 경우 함수 밖에서도 사용할 수 있다.

    • 힙에서 인스턴스화 되는 원리이다.

함수 데코레이터

  • 이미 만들어진 함수에 동작을 추가한다.

  • 함수를 래핑(Wrapping)하여 함수의 앞뒤에 코드를 자동으로 추가한다.

    • 다음 코드에서 inner = outer(inner)의 동작을 키워드식으로 해결하는 것과 같다.

      def inner():
          print("결과를 출력합니다.")
      
      def outer(func):
          def wrapper():
              print("-"*20)
              func()
              print("-"*20)
          return wrapper
      
      inner = outer(inner)
      inner()
      
      ''' stdout
      --------------------
      결과를 출력합니다.
      --------------------
      '''
      def outer(func):
          def wrapper():
              print("-"*20)
              func()
              print("-"*20)
          return wrapper
      
      @outer
      def inner():
          print("결과를 출력합니다.")
      
      inner()
      
      ''' stdout
      --------------------
      결과를 출력합니다.
      --------------------
      '''

'Python > Syntax' 카테고리의 다른 글

파이썬 모듈과 패키지  (0) 2021.08.24
파이썬 파일  (0) 2021.08.24
파이썬 예외 처리  (0) 2021.08.24
파이썬 표준 모듈  (0) 2021.08.24
파이썬 컬렉션 관리  (0) 2021.08.24