본문 바로가기

Programming/Python

파이썬 이터러블 객체, 이터레이터, 제너레이터, 데코레이터

이터러블 객체

 이터러블(iterable) 객체란 순회할 수 있는 객체를 말한다. 대표적으로 리스트, set, 딕셔너리 등이 있다. 또한 range의 리턴값도 이터러블 객체이다. 이터러블 객체 여부는 __iter__() 메서드의 유무로 확인할 수 있다. 또한 이터러블 객체는 for문에 넣으면 이터레이터로 사용할 수 있다.

[1, 2, 3].__iter__()
#<list_iterator at 0x7fa1687d0640>

 

이터레이터

 이터레이터는 다음 원소 하나하나에 접근할 수 있는 객체이다. __iter__() 메서드는 이터레이터를 반환한다. 모든 이터레이터는 이터러블 객체라고 할 수 있다. 이터레이터는 이터러블 객체와 달리 __next__() 메서드를 사용할 수 있다.

iter = [1, 2, 3].__iter__()
iter.__next__()
#1

 

제너레이터

 제너레이터는 작업의 효율성을 위해서 사용되는 방법이다. 제너레이터는 많은 양의 데이터를 리턴하는 함수가, 중간중간 데이터를 리턴하여 이후 작업을 먼저 시작할 수 있도록 한다 

제너레이터는 이터레이터를 생성하여, 많은 데이터를 모아서 사용하지않는 방식으로 메모리를 절약할 수 있는 방법이다.

 

 제너레이터 표현식

소괄호를 사용한 컴프리헨션 표현과 유사하지만, 제너레이터를 생성한다. (튜플 컴프리헨션은 소활호앞에 tuple을 명시)

(x for x in range(0,5))
#<generator object <genexpr> at 0x7fa1687992e0>

 

 

제너레이터 함수

함수 내에 yield를 사용하여 제너레이터 함수를 만들 수도 있다. 제너레이터 함수는 호출하면 제너레이터를 리턴하며, yield의 값을 바로 리턴하지 않는다. 

def gen_test():
    yield 1
    yield 2
    yield 3

gen_test()
#<generator object gen_test at 0x7fa168799510>

그래서 제너레이터 함수를 여러번 호출하면 매번 새로운 제너레이터를 생성하는 것이므로, 순서대로 1, 2, 3이 리턴되게 하기 위해서는 제너레이터를 할당 후 next()에 넣어 주면된다.

a = gen_test()
print(next(a)) #1
print(next(a)) #2

 마지막 값 이후 next를 한번더 호출하면 에러가 발생한다. 그러므로 for 문을 활용하여 에러를 방지할 수도 있다. for문에서는 자동으로 next가 호출되어 전달된다.

for i in gen_test():
	print(i)

 

 

이터러블 객체와 제너레이터의 차이

 제너레이터는 모든 데이터를 미리 만들어두고 접근하는 것이 아니라, 하나씩 생성하면서 접근하는 것이다. 즉, 제너레이터는 한번 순환된 값 또는 이후 값을 미리 저장하고 있지 않기때문에 재사용할 수 없다는 점이 다르다.

 

 

 

데코레이터

데코레이터는 다른 함수에서 기존 함수를 활용하여 기능을 추가하는 것을 말한다. 새로운 함수에서 기존에 정의된 함수를 인자로 받아 사용하는 것이다.

데코레이터는 함수를 인수로 넘겨주어서 사용할 수 도 있고, 함수 위에 데코레이터로 사용할 함수이름을 '@함수이름' 과 같은 형식으로 적어주어 항상 데코레이터와 함께 사용되게끔 만들 수 있다.

# decorator 정의
def deco(fn):
	def deco_in():
		print('decorator')
		fn()
        print('decorator')
    return deco_in

def originalPrint():
	print('original')
    
# 첫 번째 사용방법
deco(originalPrint)


# 두 번째 사용방법
@deco
def originalPrint2():
	print('original2')

originalPrint2()

데코레이터를 사용하면 기존 함수를 재활용하여 새로운 함수를 작성할 수 있다는 장점이 있다.

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

파이썬 기초 함수(map, enumerate, zip, filter)  (0) 2023.11.26
아스키 코드 - 문자 간 변환  (2) 2023.11.26
파이썬 변수 앞 * 연산자  (0) 2023.11.25
__dict__ 와 __slots__  (0) 2023.07.11
Pylint  (0) 2023.01.30