산업 제조
산업용 사물 인터넷 | 산업자재 | 장비 유지 보수 및 수리 | 산업 프로그래밍 |
home  MfgRobots >> 산업 제조 >  >> Industrial programming >> python

파이썬 데코레이터

Python 데코레이터

데코레이터는 함수를 받아서 몇 가지 기능을 추가하고 반환합니다. 이 튜토리얼에서는 데코레이터를 만드는 방법과 사용해야 하는 이유를 배웁니다.

동영상:Python의 @Decorators

Python의 데코레이터

Python에는 데코레이터라는 흥미로운 기능이 있습니다. 기존 코드에 기능을 추가합니다.

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

<시간>

데코레이터를 배우기 위한 전제 조건

데코레이터에 대해 이해하려면 먼저 Python의 몇 가지 기본 사항을 알아야 합니다.

우리는 파이썬의 모든 것(예! 심지어 클래스까지)이 객체라는 사실에 익숙해져야 합니다. 우리가 정의하는 이름은 단순히 이러한 개체에 바인딩된 식별자입니다. 함수도 예외는 아니며 객체이기도 합니다(속성 포함). 동일한 함수 개체에 다양한 이름을 바인딩할 수 있습니다.

다음은 예입니다.

def first(msg):
    print(msg)


first("Hello")

second = first
second("Hello")

출력

Hello
Hello

코드를 실행하면 두 함수 모두 firstsecond 동일한 출력을 제공합니다. 여기에서 이름 firstsecond 동일한 함수 개체를 참조하십시오.

이제 상황이 점점 이상해지기 시작합니다.

함수는 다른 함수에 인수로 전달할 수 있습니다.

map와 같은 기능을 사용한 경우 , filterreduce Python에서는 이에 대해 이미 알고 있을 것입니다.

다른 함수를 인수로 사용하는 이러한 함수를 고차 함수라고도 합니다. . 다음은 그러한 기능의 예입니다.

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()

# Outputs "Hello"
new()

출력

Hello

여기 is_returned() is_called()를 호출할 때마다 정의되고 반환되는 중첩 함수입니다. .

마지막으로 Python의 클로저에 대해 알아야 합니다.

<시간>

데코레이터로 돌아가기

함수와 메서드를 호출 가능이라고 합니다. 호출할 수 있습니다.

사실, 특별한 __call__()를 구현하는 모든 객체는 메서드를 호출 가능이라고 합니다. 따라서 가장 기본적인 의미에서 데코레이터는 콜러블을 반환하는 콜러블입니다.

기본적으로 데코레이터는 함수를 받아서 몇 가지 기능을 추가하고 반환합니다.

def make_pretty(func):
    def inner():
        print("I got decorated")
        func()
    return inner


def ordinary():
    print("I am ordinary")

쉘에서 다음 코드를 실행하면

>>> ordinary()
I am ordinary

>>> # let's decorate this ordinary function
>>> pretty = make_pretty(ordinary)
>>> pretty()
I got decorated
I am ordinary

위에 표시된 예에서 make_pretty() 데코레이터입니다. 할당 단계에서:

pretty = make_pretty(ordinary)

함수 ordinary() 장식되고 반환된 함수에 pretty이라는 이름이 지정되었습니다. .

데코레이터 함수가 원래 함수에 몇 가지 새로운 기능을 추가했음을 알 수 있습니다. 이것은 선물을 포장하는 것과 유사합니다. 데코레이터는 래퍼 역할을 합니다. 장식된 대상(실제 내부 선물)의 특성은 변경되지 않습니다. 하지만 지금은 (장식을 해서) 이뻐 보입니다.

일반적으로 함수를 장식하고 다음과 같이 재할당합니다.

ordinary = make_pretty(ordinary).

이것은 일반적인 구조이며 이러한 이유로 Python에는 이를 단순화하는 구문이 있습니다.

@을 사용할 수 있습니다. 기호를 데코레이터 함수의 이름과 함께 추가하고 장식할 함수의 정의 위에 배치합니다. 예를 들어,

@make_pretty
def ordinary():
    print("I am ordinary")

와 동일합니다.

def ordinary():
    print("I am ordinary")
ordinary = make_pretty(ordinary)

이것은 데코레이터를 구현하기 위한 구문상의 설탕일 뿐입니다.

<시간>

매개변수로 함수 장식

위의 데코레이터는 단순했고 매개변수가 없는 함수에서만 작동했습니다. 다음과 같은 매개변수를 받는 함수가 있다면 어떨까요?

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

이 함수에는 두 개의 매개변수 a가 있습니다. 및 b . b를 전달하면 오류가 발생한다는 것을 알고 있습니다. 0으로.

>>> divide(2,5)
0.4
>>> divide(2,0)
Traceback (most recent call last):
...
ZeroDivisionError: division by zero

이제 이 경우에 오류가 발생하는지 확인하는 데코레이터를 만들어 보겠습니다.

def smart_divide(func):
    def inner(a, b):
        print("I am going to divide", a, "and", b)
        if b == 0:
            print("Whoops! cannot divide")
            return

        return func(a, b)
    return inner


@smart_divide
def divide(a, b):
    print(a/b)

이 새로운 구현은 None를 반환합니다. 오류 조건이 발생하는 경우.

>>> divide(2,5)
I am going to divide 2 and 5
0.4

>>> divide(2,0)
I am going to divide 2 and 0
Whoops! cannot divide

이런 식으로 매개변수를 받는 함수를 꾸밀 수 있습니다.

예리한 관찰자는 중첩된 inner()의 매개변수가 데코레이터 내부의 함수는 데코레이터가 장식하는 함수의 매개변수와 동일합니다. 이를 고려하여 이제 여러 매개변수와 함께 작동하는 일반 데코레이터를 만들 수 있습니다.

Python에서 이 마법은 function(*args, **kwargs)로 수행됩니다. . 이런 식으로 args 위치 인수와 kwargs의 튜플이 됩니다. 키워드 인수의 사전이 됩니다. 이러한 데코레이터의 예는 다음과 같습니다.

def works_for_all(func):
    def inner(*args, **kwargs):
        print("I can decorate any function")
        return func(*args, **kwargs)
    return inner
<시간>

Python에서 데코레이터 연결

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

즉, 함수는 다른(또는 동일한) 데코레이터로 여러 번 데코레이션될 수 있습니다. 원하는 기능 위에 데코레이터를 배치하기만 하면 됩니다.

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("Hello")

출력

******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Hello
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************

위의 구문,

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

와 동일합니다.

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

데코레이터를 연결하는 순서가 중요합니다. 순서를 반대로 했다면

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

출력은 다음과 같습니다.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
******************************
Hello
******************************
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

python

  1. 파이썬 데이터 유형
  2. 파이썬 연산자
  3. 파이썬 통과 문
  4. 파이썬 함수 인수
  5. Python 익명/람다 함수
  6. 예제가 있는 Python Lambda 함수
  7. Python abs() 함수:절대값 예제
  8. 예제가 있는 Python round() 함수
  9. Python range() 함수:Float, List, For 루프 예제
  10. 예제가 있는 Python map() 함수