Python 데코레이터에 대한 심층적인 이해

高洛峰
풀어 주다: 2017-01-23 14:41:54
원래의
1097명이 탐색했습니다.

데코레이터 소개:

데코레이터는 고급 Python 구문입니다. 데코레이터는 함수, 메서드 또는 클래스를 처리할 수 있습니다. Python에서는 함수와 클래스를 처리하는 다양한 방법이 있습니다. 예를 들어 Python 클로저에서는 함수 객체를 특정 함수의 반환 결과로 봅니다. 다른 방법에 비해 데코레이터 구문이 간단하고 코드 가독성이 높습니다. 따라서 데코레이터는 Python 프로젝트에서 널리 사용됩니다.

데코레이터는 Python 2.5에서 처음 등장했습니다. 원래는 함수 및 메서드와 같은 호출 가능 개체(호출 가능 개체는 __call__ 메서드로 정의됨)를 처리하는 데 사용되었습니다. Python 2.6 및 이후 Python 버전에서는 데코레이터가 클래스를 처리하는 데 추가로 사용됩니다.

데코레이터는 주로 로그 인쇄, 함수 타이밍, 신원 인증과 같은 일부 일반적인 기능에 대해 함수를 래핑하는 데 사용됩니다. 이를 달성하기 위해 데코레이터를 사용할 수 있으며, 이는 전체 프로그램의 복잡성을 줄이고 프로그램의 코드 양을 줄일 수 있습니다.

실제로는 함수이지만 함수를 매개변수로 사용하고 함수의 대체 버전을 반환한다는 점이 다릅니다.

간단한 예를 살펴보겠습니다.

def add_number(func):
def adder(arg):
return func(arg)+100
return adder
def f(x):
return x
f=add_number(f)
print f(20)
로그인 후 복사

add_number는 함수(f)를 매개변수로 받아들이고 다른 함수( adder)를 원래 함수에 할당하여, 추가 코드를 추가하지 않고도 원래 함수에서 덧셈 기능을 구현할 수 있도록 했습니다.

이것은 데코레이터의 원래 구현입니다.

그러나 이 방법은 여전히 ​​약간 불편합니다. 결국 우리는 여전히 원을 그리며 f=add_number(f)를 사용하여 원래 함수를 다시 할당합니다.

실제로 Python에서 데코레이터에 대한 참조를 단순화하는 데 다음 방법을 사용할 수 있습니다.

def add_number(func):
def adder(arg):
return func(arg)+100
return adder
@add_number
def f(x):
return x
print f(20)
로그인 후 복사

간단한 @add_numbe 호출만 있으면 됩니다. 훨씬 간단하고 기본적으로 원본 코드를 침해하지 않습니다. <…


예, Python은 데코레이터 작성을 크게 단순화할 수 있는 데코레이터 패키지를 제공합니다.


그래서 세 번째 구현 방법은

from decorator import decorator
@decorator
def wrapper(func,arg):
return func(arg)+100
@wrapper
def f(x):
return x
print f(20)
로그인 후 복사

아, 정말 간단하네요~


위의 예는 허용됨 모두 하나의 매개변수를 갖습니다. 실제로 함수 자체는 가변 매개변수를 허용할 수 있습니다.


예:

@decorator
def wrapper(f,arg1,*args,**kwargs):
print "I am just a wrapper~"
return f(arg1,*args,**kwargs)
@wrapper
def f(arg1,*args,**kwargs):
print arg1
for eacheArg in args:
print &#39;non-keyword arg:&#39;,eacheArg
for eachKw in kwargs.keys():
print &#39;keyword arg: %s:%d&#39; % (eachKw,kwargs[eachKw])
args=(&#39;Joy&#39;,&#39;Steve&#39;)
kwargs={"age":20}
f(&#39;China&#39;,*args,**kwargs)
로그인 후 복사

출력 결과는 다음과 같습니다.

I am just a wrapper~
China
non-keyword arg: Joy
non-keyword arg: Steve
keyword arg: age:20
로그인 후 복사

*args와 *args의 차이점 **kwargs , 둘 다 가변 길이 인수를 나타내는 데 사용할 수 있습니다. 단지 전자는 Yuanzu로 표현되며 키 값이 없고, 후자는 키 값이 있는 사전입니다. 둘 다 동일한 함수에서 사용될 수 있지만 *args는 **kwargs 앞에 와야 합니다.


예:

def test_var_args_call(arg1, arg2, arg3):
print "arg1:", arg1
print "arg2:", arg2
print "arg3:", arg3
args=(1,2,3)
kwargs ={"arg1":"1","arg3": 3, "arg2": "2"}
test_var_args_call(*args)
print &#39;-----------------&#39;
test_var_args_call(**kwargs)
로그인 후 복사

두 가지 구현은 동일한 효과를 갖습니다.


마지막 예제는 함수의 실행시간을 표시하여 함수를 꾸미는 것입니다.

import time
def log(func):
def wrapper(*args, **kw):
print &#39;[%s] %s() was called...&#39; % (time.ctime(),func.__name__)
return func(*args, **kw)
return wrapper
@log
def foo():
pass
for i in range(4):
foo()
time.sleep(1)
로그인 후 복사

출력 결과는 다음과 같습니다.

[Wed Jul 27 09:17:23 2016] foo() was called...
[Wed Jul 27 09:17:24 2016] foo() was called...
[Wed Jul 27 09:17:25 2016] foo() was called...
[Wed Jul 27 09:17:26 2016] foo() was called...
로그인 후 복사

이상은 편집자가 소개한 Python 데코레이터에 대한 심층적인 이해입니다. 궁금한 점이 있으면 메시지를 남겨주시면 편집자가 답변해 드리겠습니다. 당신은 시간에. 또한 PHP 중국어 웹사이트를 지원해 주신 모든 분들께 감사드립니다!

Python 데코레이터 관련 글을 좀 더 깊이 있게 이해하고 싶다면 PHP 중국어 홈페이지를 주목해주세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿