요약
- 데코레이터를 사용했을 때, 데코레이터 함수는 원본 함수의 정보와 Docs에 대한 정보를 더 이상 반환하지 않는다.
- 데코레이터를 이렇게 사용하면 디버깅 하는 과정에서 잘못 동작할 수 있다.
- 이런 부분을 해결하기 위해 functools의 wraps 데코레이터를 사용해주면 된다.
Item 26. functools.wrap을 사용해 함수 데코레이터를 정의하라
# 데코레이터를 사용하면, 기존 함수의 이름과 __Docs__는 없어짐.
# 디버깅 시에 문제가 발생할 수 있음.
def deco(func):
def wrapper_func(*args, **kwargs):
print('here')
return func(*args, **kwargs)
return wrapper_func
@deco
def hello():
print('hello')
return 1
print(hello.__name__)
>>>
wrapper_func
데코레이터는 함수의 문맥을 강화하거나, 도우미 함수를 추가해서 AOP를 손쉽게 구현할 수 있도록 도와주는 기능이다. 그렇지만 한가지 문제점이 있다. 별다른 것들을 추가하지 않는다면 데코레이터 함수는 '기존 함수의 정보'를 전혀 반환하지 않는다는 것이다. 위 코드에서는 다음 정보가 없어진다.
- hello() 함수의 이름은 더 이상 hello가 아니라 wrapper_func가 된다.
- hello() 함수에 작성된 docs는 이제 없어진다.
이런 것들은 디버깅을 하는 시점에 잘못된 정보가 전달되어서 혼란을 가중시킨다. 그렇다면 기존 함수의 이름, DOCS를 유지하는 방법은 없을까?
import functools
# 데코레이터를 사용하더라도 기존 함수의 이름, doc이 잘 전달될 수 있도록
# 다음 명령어를 사용하자.
def deco(func):
@functools.wraps(func)
def wrapper_func(*args, **kwargs):
print('here')
return func(*args, **kwargs)
return wrapper_func
@deco
def hello():
print('hello')
return 1
print(hello.__name__)
>>>
hello
이를 위해서 functools 라이브러리가 제공되고, 여기서 wraps() 데코레이터를 사용하면 된다.
- @functools.wraps()를 사용하면 기존 함수의 이름과 문서를 그대로 유지할 수 있게 된다.
- 기존에는 hello_..name__을 출력했을 때 wrapper_func 라는 이름이 나왔었는데, 지금은 hello가 나오는 것을 볼 수 있다.
'프로그래밍 언어 > 파이썬' 카테고리의 다른 글
Effective Python Item 36. Iterator / Generator를 다룰 때는 itertools를 사용하라 (0) | 2024.01.13 |
---|---|
이펙티브 파이썬 Item 27. map과 filter 대신 컴프리헨션을 사용하라 (0) | 2023.10.21 |
이펙티브 파이썬 Item 25. 위치로만 인자를 지정하게 하거나 키워드로만 인자를 지정하게 해서 함수 호출을 명확하게 만들라 (1) | 2023.10.19 |
이펙티브 파이썬 Item 21. 변수 영역과 클로저의 상호작용 방식을 이해하라 (1) | 2023.10.19 |
이펙티브 파이썬 Item 65. try/except/else/finally의 각 블록을 잘 활용하라 (0) | 2023.10.18 |