functools_wrap_함수_데코레이터

매일 공부(ML)·2022년 6월 17일
0

이어드림

목록 보기
78/146

functools.wrap을 사용해 함수 데코레이터를 정의하라

데코레이터

  • 함수의 호출 전과 후의 코드를 추가로 실행 가능

  • 함수의 입력 인자, 반환 값, 함수에서 발생한 오류 접근

  • 함수의 의미 강화, 디버깅, 함수 등록의 기능에 유용하다.

  • 기호@

    • 데코레이터 호출 후 원래 함수가 속해야하는 영역에 같은 이름으로 등록
def trace(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f'{func.__name__}({args!r}, {kwargs!r})'
              f'-> {result!r}')
        return result
    return wrapper


@trace
def fibonacci(n):
    """n번째 피보나치 수를 반환한다."""
    if n in (0,1):
        return n
    return (fibonacci(n-2) + fibonacc(n-1))

""" 
@기호 사용은 fibonacci = trace(fibonacci)
"""

fibonacci(4)

#결과

fibonacci((0,),{}) ->0
wapper((0,),{})->0
fibonacci((1,),{}) ->1
wapper((1,),{})->1
fibonacci((2,),{}) ->1
wapper((2,),{})->1
fibonacci((1,),{}) ->1
wapper((0,),{})->0
fibonacci((0,),{}) ->0
wapper((1,),{})->1
fibonacci((1,),{}) ->1
wapper((1,),{})->1
fibonacci((2,),{}) ->1
wapper((2,),{})->1
fibonacci((3,),{}) ->2
wapper((3,),{})->2
fibonacci((4,),{}) ->3
wapper((4,),{})->3

#부작용: 데코레이터가 반환한 함수의 이름은 fibonacci가 아니다
부작용 해결

부작용 해결

  • wraps 도우미 함수 사용

    • 데코레이터 작성을 돕는 데코레이터
#wraps를 wrapper함수에 적용하면 wraps가 데코레이터 내부에 들어가는 함수에서 
#중요한 메타데이터 복사하여 wrapper함수 적용

from functools import wraps

def trace(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        print(f'{func.__name__}({args!r}, {kwargs!r})'
              f'-> {result!r}')
        return result
    return wrapper


@trace
def fibonacci(n):
    """n번째 피보나치 수를 반환한다."""
    if n in (0,1):
        return n
    return (fibonacci(n-2) + fibonacc(n-1))


#help함수 실행
help(fibonacci)

#Help on function fibonacci in module __main__:


fibonacci(n) #n번째 피보나치 수를 반환

#pickle 객체 직렬화도 가능
print(pickle.dumps(fibonacci))
profile
성장을 도울 아카이빙 블로그

0개의 댓글