English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Python 기본 튜토리얼

Python 프로세스 제어

Python 함수

Python 데이터 타입

Python 파일 작업

Python 객체와 클래스

Python 날짜와 시간

Python 고급 지식

Python 참조 매뉴얼

Python 데코레이터

DECORATOR는 함수를 받아서 기능을 추가하고 그 값을 반환하는 것입니다. 이 문서에서는 DECORATOR를 만드는 방법과 왜 사용하는지 배울 것입니다.

Python의 장식자는 무엇인가요?

Python에는 흥미로운 기능이 있습니다. 이는장식자로 알려져 있으며, 기존 코드에 기능을 추가할 수 있습니다.

이는 또한메타 프로그래밍프로그램의 일부가 컴파일 시에 프로그램의 다른 부분을 수정하려고 시도하기 때문입니다.

장식자 학습의 필요 조건

장식자를 이해하기 위해, 먼저 Python의 일부 기본 지식을 이해해야 합니다.

우리는 Python에서 모든 것이객체. 우리가 정의한 이름은 이러한 객체에 바인딩된 식별자입니다.함수그것도 마찬가지로, 이들은 객체(속성을 가진)입니다. 동일한 기능 객체에 다양한 이름을 바인딩할 수 있습니다.

이는 예제입니다.

def first(msg):
    print(msg)    
first("Hello")
second = first
second("Hello")

코드를 실행할 때, 이 두 함수 first와 second는 같은 출력을 제공합니다. 여기서 first와 second는 같은 기능 객체를 가리킵니다.

지금 상황이 복잡해지는 것을 느낄 수 있을 것입니다. 함수를 다른 함수에 전달할 수 있습니다.

Python에서 map, filter, reduce와 같은 함수를 사용한 적이 있다면 이미 알고 계신 것입니다.

기타 함수를 매개변수로 사용하는 이러한 함수는고차 함수. 이는 이러한 함수의 예제입니다.

def inc(x):
    return x + 1
def dec(x):
    return x - 1
def operate(func, x):
    result = func(x)
    return result

함수를 호출하는 방법은 다음과 같습니다.

>>> operate(inc,3))
4
>>> operate(dec,3))
2

또한, 함수는 다른 함수를 반환할 수 있습니다.

def is_called():
    def is_returned():
        print("Hello")
    return is_returned
new = is_called()
# 출력 "Hello"
new()

여기서 is_returned()는 내장 함수로, is_drawn()를 호출할 때마다 정의하고 반환합니다.

마지막으로, 우리는 이해해야 할 것입니다Python의 클로저.

장식자로 돌아갑니다

함수와 메서드는호출 가능한,호출할 수 있기 때문입니다.

실제로, 특수 메서드 __call__()를 구현한 객체는 호출 가능하다고 불립니다. 따라서 가장 기본적인 의미에서 장식자는 호출 가능하며 호출 가능한 것을 반환합니다.

기본적으로, 장식자는 함수를 받아들여 추가 기능을 추가하고 그것을 반환합니다.

def make_pretty(func):
    def inner():
        print("저는 데코레이션을 받았습니다")
        func()
    return inner
def ordinary():
    print("저는 일반 함수입니다")

shell에서 다음 코드를 실행할 때,

>>> ordinary()
저는 일반 함수입니다
>>> # 이 일반 함수를 데코레이션하겠습니다
>>> pretty = make_pretty(ordinary)
>>> pretty()
저는 데코레이션을 받았습니다
저는 일반 함수입니다

위의 예제에서 make_pretty()는 데코레이터로 사용되며, 할당 단계에서.

pretty = make_pretty(ordinary)

함수 ordinary()가 데코레이션을 받았으며, 반환된 함수는 pretty로 이름 지어집니다.

우리는 데코레이터 함수가 원래 함수에 새로운 기능을 추가한다고 볼 수 있습니다. 이는 선물을 포장하는 것과 비슷합니다. 데코레이터는 포장입니다. 데코레이션 전의 항목(안에 있는 선물)의 성질은 변경되지 않습니다. 하지만, 데코레이션 후에는 더 아름다워 보입니다.

보통, 함수를 데코레이션하고 다시 할당합니다.

ordinary = make_pretty(ordinary).

이는 일반적인 구조이므로, Python은 이 문법을 간소화했습니다.

@ 기호와 데코레이터 함수 이름을 함께 사용하여 데코레이터를 장식할 함수 정의 위에 두면 됩니다. 예를 들어,

@make_pretty
def ordinary():
    print("저는 일반 함수입니다")

상단 문법과 동일하게

def ordinary():
    print("저는 일반 함수입니다")
ordinary = make_pretty(ordinary)

이것은 데코레이터를 구현하는 문법 간소화입니다.

함수에 매개변수 데코레이터 사용

위의 데코레이터는 매우 간단하며, 매개변수가 없는 함수에만 적용됩니다. 우리의 함수가 다음과 같은 매개변수를 가지면 어떻게 될까요?

def divide(a, b):
    return a/b

이 함수는 두 개의 매개변수를 가집니다.ab。그리고 우리는 다음과 같이b0을 전달하면 오류가 발생합니다.

>>> divide(2,5))
0.4
>>> divide(2,0)
Traceback (최근 호출 마지막):
...
ZeroDivisionError: 나눗셈 0으로 나눔

지금부터 이 상황이 오류를 일으키는지 확인하는 데 사용할 데코레이터를 만들어 보겠습니다.

def smart_divide(func):
   def inner(a,b):
      print("나는 다음과 같은 수로 나누기를 할 것", a, "와", b)
      if b == 0:
         print("아이야! 0으로 나눌 수 없습니다")
         return
      return func(a,b)
   return inner
@smart_divide
def divide(a,b):
    return a/b

에러 상황이 발생하면, 이 새로운 구현은 None을 반환합니다.

>>> divide(2,5))
나는 나누기를 할거예요 2 와 5
0.4
>>> divide(2,0)
나는 나누기를 할거예요 2 0과
아이야! 나누기는 안됩니다

이렇게 하면, 파라미터가 있는 함수를 데코레이트할 수 있습니다.

촉박한 관찰자는 inner() 데코레이터 내부의 내장 함수의 파라미터가 데코레이션된 함수의 파라미터와 동일하다는 것을 알게 됩니다. 이 점을 고려하여, 지금으로서는 일반 데코레이터가 어떤 파라미터 수든지 사용할 수 있도록 할 수 있습니다.

파이썬에서 이 마법은 function()로 완료됩니다.*args, **kwargs)) 이렇게하면, args는 위치 파라미터입니다.튜플kwargs 대신 키워드 파라미터의딕셔너리이렇게의 데코레이터의 하나는.

def works_for_all(func):
    def inner(*args, **kwargs):
        나는 어떤 함수든 데코레이트할 수 있습니다.
        return func(*args, **kwargs)
    return inner

파이썬 연결 데코레이터

파이썬에서는 여러 데코레이터를 연결할 수 있습니다.

이렇게 말하면, 함수는 다른(또는 같은) 데코레이터를 여러 번 데코레이트할 수 있습니다. 데코레이터를 필요한 함수 위에 두면 됩니다.

def star(func):
    def inner(*args, **kwargs):
        print(""*" * 30)
        func(*args, **kwargs)
        print(""*" * 30)
    return inner
def percent(func):
    def inner(*args, **kwargs):
        print("%") * 30)
        func(*args, **kwargs)
        print("%") * 30)
    return inner
@star
@percent
def printer(msg):
    print(msg)
printer("헬로")

이렇게 출력이 됩니다.

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
헬로
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

위의 문법,

@star
@percent
def printer(msg):
    print(msg)

상단 문법과 동일하게

def printer(msg):
    print(msg)
printer = star(percent(printer))

알림 데코레이터의 순서는 중요합니다. 반대 순서로 하면,

@percent
@star
def printer(msg):
    print(msg)

실행은 이루어질

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
헬로
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%