파이썬 데코레이터 101

This article is part of python decorator series. In this article, we will learn what is decorator and how it works and how to implement a simple decorator function.



데코레이터



파이썬에서 데코레이터는 코드를 변경하지 않고 다른 함수(콜러블)의 동작을 변경할 수 있는 함수입니다. 이미 정의된 함수에 기능을 추가하는 투명한 방법을 제공합니다.

간단한 데코레이터 함수 예제




def hello_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result
    return wrapper


@hello_decorator
def add(a, b):
    return a + b


if __name__ == '__main__':
    output = add(2, 2)
    print(output)


이 예에서
  • hello_decorator 함수가 add 함수의 데코레이터로 추가되었습니다.
  • hello_decorator는 func를 인수로 사용하고, args 및 kwargs는 함수 추가에 전달되는 매개변수입니다.
  • hello_decorator는 래퍼(콜러블)를 반환하여 추가 기능의 동작을 수정합니다. 래퍼는 내부 함수이므로 범위 내에서 func, args, kwargs에 액세스할 수 있습니다. 따라서 add 함수가 호출될 때마다. 실제로 래퍼를 호출합니다.
  • 래퍼 내에서 func(*args, **kwargs)를 사용하여 함수를 실행하고 결과를 반환합니다.

  • 데코레이터에 몇 가지 인쇄 문을 추가하고 내부에서 어떤 일이 발생하는지 살펴보겠습니다.

    def hello_decorator(func):
        print(f'Decorator Init :: Begins for {func.__name__}')
    
        def wrapper(*args, **kwargs):
            print(f'Decorator execution :: Begins for {func.__name__}')
            result = func(*args, **kwargs)
            print(f'Decorator execution :: Ends for {func.__name__}')
            return result
    
        print(f'Decorator Init :: Ends for {func.__name__}')
        return wrapper
    
    
    @hello_decorator
    def add(a, b):
        return a + b
    
    
    if __name__ == '__main__':
        output1 = add(2, 2)
        print('Result:: ', output1)
    
        output2 = add(4, 2)
        print('Result:: ', output2)
    



    Decorator Init :: Begins for add
    Decorator Init :: Ends for add
    Decorator execution :: Begins for add
    Decorator execution :: Ends for add
    Result::  4
    Decorator execution :: Begins for add
    Decorator execution :: Ends for add
    Result::  6
    


    작동 방식



    데코레이터는 다른 함수(호출 가능)를 인수로 받아 몇 가지 작업을 수행한 다음 해당 인수 또는 콜러블을 반환하는 함수(호출 가능)입니다. Python 클래스를 데코레이터로 사용할 수도 있습니다.



    후드 아래에서 일어나는 일



    @ 구문을 사용하지 않고 동일한 데코레이터를 구현해 보겠습니다.

    def hello_decorator(func):
        print(f'Decorator Init :: Begins for {func.__name__}')
    
        def wrapper(*args, **kwargs):
            print(f'Decorator execution :: Begins for {func.__name__}')
            result = func(*args, **kwargs)
            print(f'Decorator execution :: Ends for {func.__name__}')
            return result
    
        print(f'Decorator Init :: Ends for {func.__name__}')
        return wrapper
    
    
    
    def add(a, b):
        return a + b
    
    # This is equivalent to the @ syntax
    add = hello_decorator(add)
    
    if __name__ == '__main__':
        output1 = add(2, 2)
        print('Result:: ', output1)
    
        output2 = add(4, 2)
        print('Result:: ', output2)
    


    파이썬에서는 모든 것이 객체입니다. 함수는 일급 객체입니다. 이를 변수에 할당하고, 데이터 구조에 저장하고, 다른 함수에 인수로 전달하고, 다른 함수의 값으로 반환할 수도 있습니다.

    위의 예에서 함수 add는 hello_decorator에 인수로 전달된 다음 add 함수가 대체됩니다. 이제 add를 호출하면 hello_decorator(add)를 호출합니다. @ 데코레이터는 구문 설탕일 뿐입니다.

    데코레이터는 왜?


  • 읽기 쉬움 - 데코레이터는 단일 함수에 너무 많은 논리를 채우지 않고 쉽게 읽고 수정할 수 있습니다.
  • DRY - Don't Repeat Yourself - 데코레이터를 사용하면 코드를 쉽게 재사용할 수 있습니다.

  • 가장 인기 있는 예



    표준 파이썬에서 사용할 수 있는 많은 내장 데코레이터가 있으며 많은 인기 있는 도구와 프레임워크에서 데코레이터를 많이 사용합니다. 몇 가지 예,
  • 플라스크 - @app.route @app.before_request @app.after_request @app.teardown_request
  • 장고 - @login_required @csrf_exempt @ require_http_methods
  • Python 클래스 - @classmethod @staticmethod @property
  • 단위 테스트 모의 라이브러리 - @unittest.mock @mock.patch

  • 다음 기사에서는 이 간단한 데코레이터 기능을 즉흥적으로 만들어 보겠습니다. 다가오는 기사를 계속 지켜봐주십시오. 내 미래 기사를 얻으려면 나와 연결하십시오.

    좋은 웹페이지 즐겨찾기