본문 바로가기
Python/study

@wrap

by 르면가게 2025. 1. 15.

기본 개념

Python에서 데코레이터를 사용하면 함수가 다른 함수로 래핑됩니다. 하지만, 래핑 과정에서 원래 함수의 이름(__name__), 문서 문자열(__doc__), 기타 메타데이터가 사라질 수 있습니다.

데코레이터로 인한 문제:

from functools import wraps

def my_decorator(func):
    def wrapper(*args, **kwargs):
        """Wrapper docstring"""
        print("Before the function call")
        result = func(*args, **kwargs)
        print("After the function call")
        return result
    return wrapper

@my_decorator
def my_function():
    """Original function docstring"""
    print("The function is running")

print(my_function.__name__)  # 출력: wrapper
print(my_function.__doc__)   # 출력: Wrapper docstring
 

위 코드에서 @my_decorator를 사용한 결과, my_function의 이름과 문서 문자열이 래퍼 함수(wrapper)로 덮어씌워졌습니다.


@wraps로 해결

@wraps를 사용하면, 데코레이터가 원래 함수의 메타데이터를 유지하도록 설정할 수 있습니다.

개선된 코드:

from functools import wraps

def my_decorator(func):
    @wraps(func)  # 원래 함수의 메타데이터를 유지
    def wrapper(*args, **kwargs):
        """Wrapper docstring"""
        print("Before the function call")
        result = func(*args, **kwargs)
        print("After the function call")
        return result
    return wrapper

@my_decorator
def my_function():
    """Original function docstring"""
    print("The function is running")

print(my_function.__name__)  # 출력: my_function
print(my_function.__doc__)   # 출력: Original function docstring

동작 원리

@wraps는 내부적으로 functools.update_wrapper를 호출하여 아래와 같은 메타데이터를 래핑된 함수에 복사합니다:

  • __name__: 함수 이름
  • __doc__: 문서 문자열
  • __module__: 모듈 정보
  • __annotations__: 함수의 주석
  • 기타 메타데이터

사용 예시

1. 간단한 데코레이터:

from functools import wraps

def logger(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__} with arguments {args} and {kwargs}")
        return func(*args, **kwargs)
    return wrapper

@logger
def add(a, b):
    """Adds two numbers"""
    return a + b

print(add.__name__)  # 출력: add
print(add.__doc__)   # 출력: Adds two numbers

2. 정규 데코레이터에서 사용:

여러 데코레이터를 중첩하거나 라이브러리용 데코레이터를 구현할 때도 유용합니다.


요약

  • @wraps는 데코레이터 내부에서 사용하여 원래 함수의 메타데이터를 유지합니다.
  • 이를 사용하면 디버깅 및 문서화가 쉬워지고, 데코레이터로 인해 발생하는 부작용을 방지할 수 있습니다.
  • 항상 커스텀 데코레이터 작성 시 @wraps를 사용하는 것이 좋은 습관입니다.

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

__init__  (0) 2025.02.19
unittest 모듈  (0) 2024.12.08
@staticmethod  (0) 2024.12.08
ast.literal_eval()  (0) 2024.12.08
__str__와 __repr__  (0) 2024.12.08