# Decorator in Python

By [Primrose](https://paragraph.com/@primrose) · 2022-10-06

---

Decorator Simple Examples
-------------------------

import time 간단한 문제에서 decorator의 쓰임을 찾아보자.

decorator => 함수를 input으로 받아서 => 새로운 함수를 만들어서 리턴

함수를 받아 새로운 함수를 리턴하는 함수

    import time  
    
    def hello(name):
        print("Hello, my name is " + name)
    
    
    def track_time(func):
        def new_func(*args, **kwargs):
            start_time = time.time()
            func(*args, **kwargs)
            end_time = time.time()
            print(f"Execute Time : {end_time - start_time}")
        return new_func
    
    
    hello = track_time(hello)
    hello("primrose")
    # ##
    # 확장성을 위해 track_time이라는 데코레이터 함수를 만든다. 인자로 함수를 받고, 내부의 함수를 리턴해준다.
    # 리턴되는 함수는 데코레이터 함수 안에서 정의된 함수이고, 확장성을 위해 packing한다.
    """
    Hello, my name is primrose
    Execute Time : 2.193450927734375e-05
    """
    

위에서 hello = track\_time(hello)라는 식으로 함수를 wrapping했는데,

파이썬에서는 이것을 다음과 같이 표현이 가능하다

    다음과 같이 `advanced_hello` 함수 위에 @track_time이라고 적으면 advanced_hello 함수를 인자로 받아서 
    track_time 함수가 decorate(장식)하여 새로운 함수가 반환된다.
    이름은 advanced_hello 이지만 데코레이터가 있고 없고의 결과는 완전히 다르다.
    
    
    @track_time
    def advanced_hello(name):
        print("Hello, my name is " + name)
    
    
    advanced_hello("primrose")
    
    """
    Hello, my name is primrose
    Execute Time : 3.814697265625e-06
    """
    

위에서는 데코레이터가 하나였지만, 중첩(nested)도 가능하다.

시간을 측정하는 track\_time뿐 아니라, 시작과 끝을 알려주는 데코레이터 함수도 만들었다.

    def start(func):
        print("start_func decorator applied")
    
        def wrapper(*args, **kwargs):
            print("function is called now")
            return func(*args, **kwargs)
        return wrapper
    
    
    def finish(func):
        print("finish_func decorator applied")
    
        def wrapper(*args, **kwargs):
            result = func(*args, **kwargs)
            print("function is finished now")
            return result
        return wrapper
    
    
    @track_time
    @finish
    @start
    def nested_hello(name):
        print("Hello, my name is " + name)
    
    
    nested_hello("primrose")
    
    """
    start_func decorator applied
    finish_func decorator applied
    function is called now
    Hello, my name is primrose
    function is finished now
    Execute Time : 5.9604644775390625e-06
    """
    

아래는 간단한 데코레이터 활용 예시, 피보나치(엄연히 따지자면 메모이제이션)에서 사용 가능 !

    def cache_memoization(func):
        __cache = {}
    
        def wrapper(*args):
            if args in __cache:
                return __cache[args]
            else:
                result = func(*args)
                __cache.update({args: result})
                return result
        return wrapper
    
    
    @cache_memoization
    def fibo(n):
        return n if n < 2 else fibo(n-1) + fibo(n-2)
    
    
    fibo(100)

---

*Originally published on [Primrose](https://paragraph.com/@primrose/decorator-in-python)*
