>  기사  >  백엔드 개발  >  Python 데코레이터에 대한 자세한 설명

Python 데코레이터에 대한 자세한 설명

藏色散人
藏色散人원래의
2020-02-13 11:41:204993검색

Python 데코레이터에 대한 자세한 설명

파이썬 데코레이터 상세 설명

파이썬 데코레이터 상세 분석

데코레이터란 무엇인가요?

추천 학습: Python 동영상 튜토리얼

Python 데코레이터(fuctional 데코레이터)는 원래 함수 이름(또는 클래스 이름)을 변경하지 않고 Python을 제공하는 것이 목적입니다. 기능은 새로운 기능을 추가합니다.

이 함수의 특별한 점은 반환 값도 함수라는 것입니다. 이 함수는 "원래" 함수가 포함된 함수입니다.

일반적으로 말하면 원래 함수 코드를 확장하려는 경우 가장 많이 사용됩니다. 직접적인 방법은 코드를 수정하는 것입니다. 예:

import time
def f():
    print("hello")
    time.sleep(1)
    print("world")  

이것은 우리의 가장 독창적인 함수이며, 이 함수의 총 실행 시간을 기록하려고 합니다. 가장 쉬운 방법은 원래 코드를 변경하는 것입니다.

import time
def f():
    start_time = time.time()
    print("hello")
    time.sleep(1)
    print("world")
    end_time = time.time()
    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)

하지만 실제 작업에서는 핵심 코드를 직접 수정할 수 없는 경우가 있기 때문에 원래 코드를 변경하지 않고 다른 함수를 정의할 수 있습니다. (단, 해당 함수를 다시 실행해야 적용됩니다.)

import time
def deco(func):
    start_time = time.time()
    f()
    end_time = time.time()
    execution_time = (end_time - start_time)*1000
    print("time is %d ms" %execution_time)
def f():
    print("hello")
    time.sleep(1)
    print("world")
if __name__ == '__main__':
    deco(f)
    print("f.__name__ is",f.__name__)
    print()

여기서 deco 함수는 함수를 매개변수로 사용하고 이 함수에 타이밍 함수를 포함시킵니다. 그러나 이러한 수천만 개의 함수의 기능을 확장하려면 deco() 함수를 천만 번 실행해야 합니다. , 그래서 이것은 이상적이지 않습니다. 다음으로, 데코레이터를 사용하여 구현해 볼 수 있습니다. 먼저 데코레이터의 원래 모습을 살펴보겠습니다. value도 함수입니다.

f() 함수는 반환 함수 래퍼() 내에서 실행됩니다. 그런 다음 함수 f() 앞에 @deco를 추가하면

f() 함수는 다음과 같습니다. 타이밍 기능이 주입되었습니다. 이제 f()가 호출되는 한 "더 많은 기능을 갖춘 새로운 함수"로 변환되었습니다.

(원래 함수를 반복할 필요 없음)

확장 1: 고정 매개변수가 있는 데코레이터

.
import time
def deco(f):
    def wrapper():
        start_time = time.time()
        f()
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" %execution_time )
    return wrapper
@deco
def f():
    print("hello")
    time.sleep(1)
    print("world")
if __name__ == '__main__':
    f()

확장 2: 고정된 매개변수가 없는 데코레이터

import time
def deco(f):
    def wrapper(a,b):
        start_time = time.time()
        f(a,b)
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" % execution_time)
    return wrapper
@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
if __name__ == '__main__':
    f(3,4)

확장 3: 여러 데코레이터를 사용하여 함수 꾸미기

import time
def deco(f):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        execution_time_ = (end_time - start_time)*1000
        print("time is %d ms" %execution_time)
    return wrapper
@deco
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
@deco
def f2(a,b,c):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b+c))
if __name__ == '__main__':
    f2(3,4,5)
    f(3,4)
import time
def deco01(f):
    def wrapper(*args, **kwargs):
        print("this is deco01")
        start_time = time.time()
        f(*args, **kwargs)
        end_time = time.time()
        execution_time = (end_time - start_time)*1000
        print("time is %d ms" % execution_time)
        print("deco01 end here")
    return wrapper
def deco02(f):
    def wrapper(*args, **kwargs):
        print("this is deco02")
        f(*args, **kwargs)
        print("deco02 end here")
    return wrapper
@deco01
@deco02
def f(a,b):
    print("be on")
    time.sleep(1)
    print("result is %d" %(a+b))
if __name__ == '__main__':
    f(3,4)

Decorator 호출 순서

Decorator를 중첩할 수 있으므로 데코레이터를 사용한 후의 순서는 무엇입니까?

Python의 "@" 구문 설탕의 경우 데코레이터는 @ 구문 설탕 선언과 반대 순서로 호출됩니다.

이 예에서는 "f(3, 4) = deco01( deco02(f(3) , 4)))".

Python 내장 데코레이터

Python에는 클래스와 관련된 세 가지 내장 데코레이터가 있습니다: staticmethod, classmethod 및 property.

staticmethod 클래스 정적 메서드입니다. 클래스 메소드와 멤버 메소드의 차이점은 self 매개변수가 없으며 클래스가 인스턴스화되지 않고 호출될 수 있다는 것입니다. 클래스 메소드와 멤버 메소드의 차이점은 수신된 첫 번째 매개변수가 self(클래스 인스턴스의 포인터)가 아니라는 것입니다. ), 하지만 cls(현재 클래스의 특정 유형) property는 속성을 의미하며, 클래스 인스턴스를 통해 직접 접근할 수 있는 정보를 나타냅니다.

여기서는 staticmethod와 classmethod에 대해 소개하지 않겠습니다. 예를 통해 살펴보겠습니다.

Python 새 스타일 클래스의 경우 위의 "@var.setter" 데코레이터로 장식된 멤버 함수가 제거되면 Foo.var 속성은 읽기 전용 속성이 되며 "foo . var = 'var 2′"는 할당을 수행할 때 예외를 발생시킵니다. 그러나 Python 클래식 클래스의 경우 선언된 속성은 읽기 전용이 아니므로 "@var.setter" 데코레이터를 제거하더라도 오류가 보고되지 않습니다.

요약

Python 데코레이터에 대한 자세한 설명이 글에서는 Python 데코레이터의 몇 가지 용도를 소개합니다. 데코레이터의 코드는 비교적 이해하기 쉽습니다. 몇 가지 예를 통해 연습해 보면 이해하기 쉽습니다.

위 내용은 Python 데코레이터에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.