Python

Python – iterator, generator, decorator

Iterator (이터레이터)

  • Iterable 객체
    • 반복 가능한 객체
    • 문자열, 리스트, 튜플, 딕셔너리, range 등
    • Iterator 객체 – 값을 차례대로 꺼낼 수 있는 객체
    • Iterator는 객체를 내장함수 또는 iterable 객체의 메소드(매직 메소드 __iter__)로 객체를 생성
  • 매직 메소드 __iter__ 로 iterator 객체 만들어보기
# list 객체 생성
list_obj = [10, 20, 30]

# list에 대해 iterator 객체를 생성 
list_iter = list_obj.__iter__()

print(list_iter)
# <list_iterator object at 0x00000276CF9D9790>

for value in list_iter: 
   print(value) 


# 다음값을 찾는 매직 메소드 __next__ 로도 값을 찾을수있다
print(list_iter.__next__()) # 다음값이 없다면 StopIteration 에러 출력
  • 클래스로 iterator 객체 만들어보기
class CreateIter:
    def __init__(self, datas) -> None:
        self.datas = datas
        self.idx = 0
        self.max_num = len(datas)

    def __iter__(self) -> None:
        return self

    def __next__(self):
        if self.idx < self.max_num:
            current_idx = self.idx
            self.idx += 1
            return self.datas[current_idx]
        else:
            raise StopIteration

my_friends = ["jpro", "mark", "julie", "adam"]
iter_friends = CreateIter(my_friends)

print(iter_friends.__next__()) # jpro
print(iter_friends.__next__()) # mark
print(iter_friends.__next__()) # julie
print(iter_friends.__next__()) # adam
print(iter_friends.__next__()) # 더이상 다음 내용이 없기때문에 에러 발생

Generator (제너레이터)

  • generator 객체
    • 시퀀스를 생성하는 객체
    • generator 특징
      • 함수 안에 yield(일드) 키워드를 이용해서 만들수있음
      • generator 표현식 사용
      • 메모리 사용이 효율적
  • yield 키워드 사용해보기
def func():
    print("첫번째 작업")
    yield 1
    print("두번째 작업")
    yield 2
    print("세번째 작업")
    yield 3

generator_func = func()
print(generator_func.__next__()) 

>>>
첫번째 작업
1

print(generator_func.__next__())

>>>
두번째 작업
2

print(generator_func.__next__())
>>>
세번째 작업
3
  • generator 표현식
# Generator 객체 생성
double_generator = (i*1 for i in range(10))

print(double_generator)

# <generator object <genexpr> at 0x0000027F543C14A0>

for i in double_generator: print(i)
>>>
0
1
2
3
4
5
6
7
8
9
  • 메모리 사용이 효율적인 이유
import sys

list_data = [i for i in range(1,10001)]
generator_data = (i for i in range(1,10001))

# 리스트는 결과값을 계산해서 메모리상에 저장
print(sys.getsizeof(list_data)) # 87616

# 결과값을 그때그때 계산해서 __next__로 가져옴 메모리상에는 그때그때 계산된 결과값만 저장 
print(sys.getsizeof(generator_data)) # 112

Decorator (데코레이터)

  • decorator 객체
    • 하나의 함수를 취해서 또 다른 함수를 반환하는 함수
    • decorator 특징
      • 함수 실행 전/후에 부가적인 기능을 넣어주는 용도
      • 로깅, 권한
      • 형식 – @메서드종류
  • decorator로 간단한 로그인 기능 구현해보기
def login_wrapper(func):
    def wrapper(id=None, passoword=None, type="login"):
        
        if type == "login":
            print("login start")
            login_result = func(id, passoword)

            if login_result: print("login success")
            else: print("login fail")

            print("login end")

        elif type == "logout":
            print("logout start")

            func(id)

            print("logout end")
        
    return wrapper

@login_wrapper
def login(id, password):
    if id == "jpro" and password == "password": return True
    else: return False

@login_wrapper
def logout(id):
    if id == "jpro": print("logout success")

login("jpro", "password")
logout(id="jpro", type="logout")

>>>
login start
login success
login end
logout start
logout success
logout end

참고 자료

댓글 한 개

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.