Python decorator
Definition: The essence is a function, (decorating other functions) is to add additional functions for other functions
Principle:
1. Cannot modify the source code of the decorated function
2. Can not modify the original function call mode
Knowledge Reserve: 1. The function is executed by the variable function when the interpreter executes from top to bottom 2. Higher order functions
A. Pass a function name as an argument to another function (you can add a function to it without modifying the source code of the function) B. The return value contains the function name 3. Nested functions
When the adorner requires three-level nesting of parameters, no two-level nesting of parameters is required
Adorner possible application as a function
The simplest way to create an adorner is to write a function that returns a child function that wraps the original function call
def mydecorator(function): def wrapped(*args,**kwargs): #调用原始函数之前做的操作 result=function(*args,**kwargs) #调用原始函数之后做点什么 #返回结果 return result #返回wrapper作为装饰函数 return wrapped
As a class
In most cases adorners are always implemented with functions, but in some cases it is better to use classes. If the adorner requires complex parameterization or is dependent on a particular state, the adornment class is used
Common mode
class DecoratorAsClass:
def __init__(self,function):
self.function=function
def __call__(self,*args,**kwargs):
#在调用原始函数指点,做点什么
result=self.function(*args,**kwargs)
#在调用原始函数之后做点什么
#返回函数执行结果
return result
@DecoratorAsClass
def hello():
print(‘hello‘)
hello()
Parametric decorators
The actual use of adorners requires the use of parameterized adorners. Class decorators Needless to say, you can pass in parameters when you initialize. In the case of a function as an adorner, a second layer of packaging is required. If you need to execute a primitive function more than once, and the number of repetitions is given by the adorner parameter, here is the sample code
def repeat(number=3):
"""多此执行装饰函数,返回最后一次执行结果
参数名为 number:重复次数,默认为3
"""
def erceng_decorator(function):
def wrapper(*args,**kwargs):
result=None
for _ in range(number):
result=function(*args,**kwargs)
return result
return ercent_decorator
@repeat(2)
def hello():
print("hello")
hello()
hello
hello
The parameter has a default value when using a parameterized adorner, but the name must be appended with parentheses, or an error will be given.
Preserving an introspective adorner
The common problem with adorners is the inability to save the original function's metadata (document string and function name), the adorner combination creates a new function, returns a new object, but does not take into account the identity of the original function. This time the debugging is troublesome, unable to find the original function, will also destroy the tool to automatically generate documents, unable to access the original function of the document string
def dummy_dec(function):
... def wrapped(*args,**kwargs):
... """包装函数内部文档。"""
... return wrapped
@dummy_dec
... def function_important_doc():
... """这是重要文档"""
function_important_doc.__name__
‘wrapped‘
>>> function_important_doc.__doc__
‘包装函数内部文档。‘
As shown above, the original function's name and document have been modified, it is easy to solve this problem, using the Functools module built-in wraps () Adorner:
from functools import wraps
def chuli_dec(function):
@wraps(function)
def wrapper(*args,**kwargs):
"""包装函数文档"""
return function(*args,**kwargs)
return wrapper
@chuli_dec
def func_import_doc():
"""这是重要文档"""
print(func_import_doc.__name__)
print(func_import_doc.__doc__)
func_import_doc
这是重要文档
Like the top handle, that's right.
Python Decorator Ultimate Mystery