티스토리 뷰

9.7. 잡동사니

  • C의 struct(구조체)처럼 메소드 없이 새로운 데이터 타입을 정의하는데만 클래스를 쓰는 것도 충분히 유용한 사용법이다.

    class Employee:
        pass
    
    john = Employee()  # 빈 employee 레코드를 만든다.
    
    # 레코드의 내용을 채운다.
    john.name = 'John Doe'
    john.dept = 'Com. Sci.'
    john.salary = 1000
  • 인스턴스 메소드 객체도 어트리뷰트를 갖는다.

  • m.__self__는 메소드 m()과 결합한 인스턴스 객체이고, m.__func__는 메소드에 상응하는 함수 객체이다.

    class M:
        def m():
            pass
    
    print(a.m.__self__)  # <__main__.M object at 0x000001A9EEE4DD68>
    print(a.m.__func__)  # <function M.m at 0x000001A9EEE28D90>

9.8. 이터레이터

  • 많이들 눈치 챘듯이 대분의 컨테이너 객체들은 for문으로 루핑할 수 있다.

    for element in [1, 2, 3]:
        print(element)
    for element in (1, 2, 3):
        print(element)
    for key in {'one':1, 'two':2}:
        print(key)
    for char in "123":
        print(char)
    for line in open("myfile.txt"):
        print(line, end='')
  • for문은 컨테이너 객체에 대해 iter()를 호출한다. 이 함수는 메소드 __next__()를 정의하는 이터레이터 객체를 돌려주는데, 이 메소드는 컨테이너의 요소들을 한 번에 하나씩 액세스 한다.

  • __next__() 함수는 남은 요소가 없으면 StopIteration 예외를 일으키고 for루프 종료를 알린다.

    s = 'abc'
    it = iter(s)
    print(it)  # <iterator object at 0x00A1DB50>
    print(next(it))  # 'a'
    print(next(it))  # 'b'
    print(next(it))  # 'c'
    next(it)
    # Traceback (most recent call last):
    # File "<stdin>", line 1, in <module>
    #     next(it)
    # StopIteration
  • 이터레이터의 매커니즘을 잘 이해한다면, 커스텀 클래스에 이터레이터 동작을 쉽게 추가할 수 있다. 클래스가 __next__()를 정의한다면, __iter__()는 그냥 self만 리턴하면 된다.

    class Reverse:
        """Iterator for looping over a backwards."""
        def __init__(self, data):
            self.data = data
            self.index = len(data)
    
        def __iter__(self):
            return self
    
        def __next__(self):
            if self.index == 0:
                raise StopIteration
            self.index = self.index - 1
            return self.data[self.index]
    
    rev = Reverse('spam')
    print(iter(rev))  # <__main__.Reverse object at 0x00A1DB50>
    for char in rev:
        print(char)
    
    # m
    # a
    # p
    # s

9.9. 제너레이터

  • 제너레이터는 이터레이터를 만드는 간단하고 강력한 도구이다.

  • 일반적으로 함수처럼 사용되지만 값을 돌려주고 싶을 때 마다 yield문을 사용한다.

  • 제너레이터에 next()가 호출될 때마다, 제너레이터는 떠난 곳에서 실행을 재개한다.

    def reverse(data):
        for index in range(len(data)-1, -1, -1):
            yield data[index]
    
    for char in reverse('golf'):
        print(char)
    
    # f
    # l
    # o
    # g
  • 제너레이터는 __iter__()__next__() 메소드를 자동을 만들기 떄문에 간단하다.

  • 다른 주요 기능은 지역 변수들과 실행 상태가 호출 간에 자동을 보관된다는 것이다.

  • 마지막으로 제너레이터가 종료할 때 자동으로 StopIteration을 일으킨다.

9.10. 제너레이터 표현식

  • 간단한 제너레이터는 리스트 컴프리헨션과 비슷하지만, [, ]대신 (, )을 사용한다.

  • 이 표현식들은 둘러싸는 함수가 제너레이터를 즉시 사용하는 상황을 위해 설계 되었다.

  • 제너레이터 표현식은 완전한 제너레이터 정의보다 간결하지만 융통성은 떨어지고, 리스트 컴프리헨션보다 메모리를 덜 쓰는 경향이 있다.

  •  

    sum(i*i for i in range(10))  # sum of squares
    # 285
    
    xvec = [10, 20, 30]
    yvec = [7, 5, 3]
    sum(x*y for x, y in zip(xvec, yvec))  # dot product
    # 260
    
    from math import pi, sin
    sine_table = {x: sin(x*pi/180) for x in range(0, 91)}
    unique_words = set(word for line in page for word in line.split())
    valedictorian = max((student.gpa, student.name) for student in graduates)
    data = 'golf'
    list(data[i] for i in range(len(data) - 1, -1, -1))
    # ['f', 'l', 'o', 'g']

     

Reference: 파이썬 자습서

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
글 보관함