-
[Python] Decorator개발 2024. 5. 17. 10:45
파이썬에선 함수위에 데코레이터를 둬서 함수의 실행전후에 특정한 작업을 주입할 수 있다. 아래 코드에선 foo 함수에 logging 이란 데코레이터를 추가했고 실행 전에 before 실행 후엔 after 를 출력하도록 했다.
def logging(func): def wrapper(*args, **kwargs): print("before") ret = func(*args, **kwargs) print("after") return ret return wrapper @logging def foo(): print("foo") foo()
실행 결과 의도했던 대로 출력된다. 로깅이나 실행 전후에 처리하고 싶은 로직을 넣어야하는 경우 유용하게 사용할 수 있다.
before foo after
그런데 데코레이터를 사용할때 주의할 점이 있다. 아래 코드를 실행하면 어떤 결과가 나올까?
def logging(func): def logs(*args, **kwargs): return func(*args, **kwargs) return logs @logging def foo(x): return x + 100 print(foo.__name__)
애초 우리가 의도한건 foo 의 함수 객체의 이름이므로 foo 가 출력돼야 한다. 그런데 결과 값은 데코레이터의 wrapper 함수인 logs 가 출력된다. 데코레이터 wrapper 함수를 사용하면서 기존 foo 함수의 __name__ 과 __doc__ 같은 정보가 덮어썼기 때문이다.
logs
파이썬의 functools 라는 라이브러리에서는 데코레이터의 이런 문제점을 보완하고자 functions.wraps 라는 함수를 제공한다. 데코레이터를 쌩으로 쓰지 않고 functions.wraps 를 사용하면 기존 함수의 정보가 보존된다.
from functools import wraps def logging_wrapped(func): @wraps(func) def logs(*args, **kwargs): print(func.__name__ + " was called") return func(*args, **kwargs) return logs @logging_wrapped def foo_wrapped(x): return x + 100 print(foo_wrapped.__name__) # foo_wrapped
'개발' 카테고리의 다른 글
Sentry 에서 Clickhouse 를 택한 이유 (0) 2024.08.20 [파이썬] 파이썬은 모든것이 객체다 (0) 2024.05.09 [python] __all__ 을 이용해 전체 임포트 막기 (0) 2024.05.08 __init__.py 를 이용한 모듈 관리 (0) 2024.05.08 파이썬 - 리스트 컴프리헨션 (0) 2024.05.03