ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python | Python 데코레이터(Decorator)
    python 2022. 1. 26. 18:02

    파이썬의 데코레이터에 대해서 정리합니다.

     

    파이썬의 웹 프레임워크나 라이브러리들을 사용할 때 @로 시작하는 것을 확인할 수 있습니다.

    이를 파이썬에서는 데코레이터라고 합니다.

    데코레이터(Decorator)는 기존 함수의 변경 없이 추가적인 기능을 덧붙일 수 있도록 해 주는 함수라고 보시면 됩니다.

     

    간단하게 메서드의 시간을 측정하는 기능을 하는 데코레이터를 만들어 보면서 데코레이터가 어떤 것인지 정리해보도록 하겠습니다.

    데코레이터는 함수와 클래스 둘 다 이용하여 만들 수 있습니다.

     

    데코레이터(함수)

    from time import sleep, perf_counter
    
    def time_check_func(func):
        def check(*args):
            start = perf_counter()
            func(*args) # 받아온 함수 실행!
            end = perf_counter()
            print(f'>> {start} / {end} / {end - start}')
    
        return check
    

    다음과 같이 데코레이터는 함수를 매개변수로 받아서 내부의 함수에서 실행하는 구조로 되어있습니다.

     

    위와 같은 함수를 이용해서 시간을 측정한다고 했을 경우 다음과 같이 할 수 있습니다.

    # 테스트 함수
    def test_decorator_func(*args):
        print(f'run function decorator >> {args}')
        sleep(1)
    
    time_check_func(test_decorator_func)('A','B','C','D')
    # run function decorator >> ('A', 'B', 'C', 'D')
    # >> 290215.2574023 / 290216.2585761 / 1.0011737999739125
    

    다음과 같이 time_check_func이라는 함수에 매개변수로 test_decorator_func을 넣고 time_check_func내부의 check를 이용하여 호출하게 되는 것인데, 너무 코드가 길어지고 복잡해집니다.

     

    이때 데코레이터를 이용하면 쉽게 사용할 수 있습니다.

    @time_check_func
    def test_decorator_func(*args):
        print(f'run function decorator >> {args}')
        sleep(1)
    
    test_decorator_func('A','B','C','D')
    # run function decorator >> ('A', 'B', 'C', 'D')
    # >> 290215.2574023 / 290216.2585761 / 1.0011737999739125
    
    @time_check_func
    def other_func():
        print('other function run')
        sleep(2)
    
    other_func()
    # other function run
    # >> 290877.8528502 / 290879.8550702 / 2.002219999965746
    

    테스트 함수 위에 @time_check_func를 작성하게 되면 이전에 사용한 것처럼 동작하게 됩니다.

    또한 다른 함수들에도 데코레이터를 재사용함으로써 시간을 측정하는 기능을 손쉽게 적용할 수 있습니다.

     

    데코레이터(클래스)

    class time_check_cls:
        def __init__(self, func):
            self._func = func
    
        def __call__(self):
            start = perf_counter()
            self._func()
            end = perf_counter()
            print(f'>> {start} / {end} / {end - start}')
    

    클래스 형태로 데코레이터를 작성할 경우 init 메서드에 매개변수로 func을 받도록 하고,

    call 메서드를 구현함으로써 생성할 수 있습니다.

     

    사용은 함수로 만든 경우와 동일하게 사용할 수 있습니다.

    @time_check_cls
    def test_decorator_cls():
        print('run class decorator')
        sleep(1)
    
    test_decorator_cls()
    # run class decorator
    # >> 290879.8553817 / 290880.8566954 / 1.00131370004965
    

     

    마무리

    파이썬 데코레이터에 대해서 정리해보는 시간이었습니다.

    파이썬에서는 데코레이터가 자주 사용되는 것을 확인할 수 있었습니다. Flask의 @route부터 시작해서 pythontips에서 예시로 제공한 인증처리 등 앞으로 파이썬으로 코딩을 하면서 데코레이터를 제대로 활용할 수 있으면 많은 도움이 될 것 같은 생각이 들었습니다.

     

    감사합니다.

     

    참고자료

    https://book.pythontips.com/en/latest/decorators.html#giving-a-function-as-an-argument-to-another-function

    https://dojang.io/mod/page/view.php?id=2427

    'python' 카테고리의 다른 글

    Python | Python 일급 함수(First Class function)  (0) 2022.01.26
    Python | Python 내부 동작과정  (0) 2022.01.24
    Python | Class에 대해서  (0) 2022.01.23
Designed by Tistory.