IT/Python

데코레이터

우루사이 2023. 11. 18. 23:56

데코레이터란

  • 클로저를 이용해 함수 동작을 확장하는 메타 프로그래밍 기법 중 하나
  • 함수를 인자로 받아 내부에서 실행하는 클로저를 정의한 후 @<클로저> 구문을 필요한 함수 앞에 표시
  • 호출자 패턴의 포장 함수를 내장한 클로저의 호출 은폐
  • @<클로저> <함수 정의> 구문은 함수 참조를 자유 변수롤 갖는 클로자의 내부 포장 함수로 변경
  • 고차 함수를 이용한 함수 호출은 일급 함수가 아닌 함수의 참조를 인자로 전달하는 고차 함수
  • 데코레이터는 고차 함수 호출을 일급 함수로 보이게 함

함수 프로파일링

  • 데코레이터를 활용하 함수에 부가기능을 추가
# example 1
import time

def p_clock(func):
    def wrapper(*args):
    	s = time.perf_counter()
        ret = func(*args)
        e = time.perf_counter() - s
        print("[{e:0.5f}s]{func.__name__}({'.'.join(repr(arg) for arg in args)}) -> {ret}")
        return ret
    return wrapper
    
@p_clock
def factorial(n):
    return 1 if n<2 else n*factorial(n-1)
    
factorial(5)
# example 2
def memoize(func):
	memo = {0:0, 1:1, 2:2}
    def wrapper(n):
        nonlocal memo
        if n in memo:
            return memo[n]
        else:
            memo[n] = func(n)
            return memo[n]
    return wrapper

count = 0

@memoize
def Fib(n):
    global count
    count += 1
    return Fib(n-1) + Fib(n-2)
    
ret = Fib(20), count

 

데코레이터 함수에 인자를 추가할 때와 아닐 때의 차이

# 인자 없을 경우
def deco_func(func):
    def wrapper(*args, *kwargs):
        return somthings(func(*args, **kwargs))
    return wrapper

@deco_func
def target_func(something):
    return something


# 인자 추가시
def deco_func(something):
    def additional(func):
        def wrapper(*args, *kwargs):
            return somthings(something, func(*args, **kwargs))
        return wrapper
    return additional

@deco_func("인자")
def target_func(something):
    return something