<>1. Definition of decorator
It is a function that adds extra functions to an existing function , It is essentially a closure function .
Functional features of decorators :
* Do not modify the source code of existing functions
* Do not modify the existing function call mode
* Add extra functionality to existing functions
The distinction between closure and decorator :
If the closure function has and only one argument , And it's a function type , So this closure function is called decorator .
Code writing should follow the open and closed principle , It stipulates that the implemented function code is not allowed to be modified , But it can be expanded .
<>2. Decorator example code
# Define decorators def decorator(func): def inner(): # Decorate the existing function in the inner function print(' Login authentication added ')
func() return inner def comment(): print(' Comment ') #
Call decorators to decorate existing functions , sinister comment=inner comment = decorator(comment) # Call mode unchanged comment()
<>3. Grammatical sugar writing of decorators
If there are multiple functions, you need to add the function of login authentication , It needs to be written every time func = decorator(func) This code decorates existing functions , This method is still troublesome .
Python It provides a more simple way to write decoration function , That's grammar sugar , What is the writing format of grammar sugar : @ Decorator name , We can also decorate the existing functions by the way of syntax sugar
# Define decorators def decorator(func): def inner(): # Decorate the existing function in the inner function print(' Login authentication added ')
func() return inner @decorator # comment = decorator(comment) Decorator syntax sugar encapsulates the code
left comment=inner def comment(): print(' Comment ') # Call mode unchanged comment()
<>4. Timing of decorator execution
When After the current module is loaded , The decorator will execute immediately , Decorate existing functions .
# Define decorators def decorator(func): print(' The decorator is working ') def inner(): # Decorate the existing function in the inner function
print(' Login authentication added ') func() return inner @decorator # comment = decorator(comment)
Decorator syntax sugar encapsulates the code left comment=inner def comment(): print(' Comment ')
Operation results :
The decorator is working
<>5. Use of decorators
<>5.1 Usage scenarios of decorators
* Statistics of function execution time
* Output log information
<>5.2 Statistics of execution time of existing functions implemented by decorators
import time def decorator(func): def inner(): # Get time distance 1970-1-1 0:0:1 Time difference of begin
= time.time() func() end = time.time() result = end - begin print(f
' Function execution time :{result}') return inner @decorator def work(): for i in range(10000):
print(i) work()
<>6. Use of universal decorators
Universal decorator : Any type of function can be decorated
When decorating existing functions with decorators , The type of the inner function is consistent with the type of the existing function to be decorated
<>6.1 Decorate functions with parameters
def decorator(func): def inner(num1, num2): print(' An effort is being made to perform the addition calculation ') func(num1, num2
) return inner @decorator def add_num(num1, num2): result = num1 + num2 print(f
' The result is :{result}') add_num(1, 2)
<>6.2 Decoration with parameters , Functions that return values
def decorator(func): def inner(num1, num2): print(' An effort is being made to perform the addition calculation ') num = func(num1
, num2) return num return inner @decorator def add_num(num1, num2): result =
num1+ num2 return result result = add_num(1, 2) print(f' The result is :{result}')
<>6.3 Decoration with variable length parameters , Functions that return values
def decorator(func): def inner(*args, **kwargs): print(' An effort is being made to perform the addition calculation ') #
*args: Put every element in the tuple , Transfer parameters according to the position parameter # **kwargs: Put every key value pair in the dictionary , Transfer parameters by keyword num = func(
*args, **kwargs) return num return inner @decorator def add_num(*args, **kwargs)
: result = 0 for value in args: result += value for value in kwargs.values():
result+= value return result result = add_num(1, 2, a=3) print(f' The result is :{result}')
<>7. Use of multiple decorators
Decoration process of multiple decorators : A decoration process from inside to outside , Perform the interior decorator first , In the execution of the external decorator .
def make_div(func): print('make_div The decorator is working ') def inner(): result = '<div>' +
func() + '</div>' return result return inner def make_p(func): print(
'make_p The decorator is working ') def inner(): result = '<p>' + func() + '</p>' return result
return inner # Principle analysis :content = make_div(make_p(content)) # Distributed disassembly :content =
make_p(content), Interior decorator complete ,content = make_p.inner # content =
make_div(make_p.inner) @make_div @make_p def content(): return ' Life is short , I use it python' c
= content() print(c) make_p The decorator is working make_div The decorator is working <div><p> Life is short , I use it python</p></div>
<>8. Decorator with parameters
The decorator with parameters can pass in the specified parameters when decorating functions with decorators , Grammatical format : @ Decorator ( parameter ,…)
Using decorators with parameters , In fact, there is a function wrapped around the decorator , Use this function to receive parameters , The return is a decorator , because @ Symbols need to be used with examples of decorators .
def return_decorator(flag): # The decorator can only take one parameter and is a function type def decorator(func): def inner
(a, b): if flag == '+': print(' An effort is being made to perform the addition calculation ') elif flag == '-': print(' Efforts are being made to perform subtraction '
) func(a, b) return inner # A decorator can be returned when the function is called decorator return decorator
@return_decorator('+') # decorator = return_decorator('+'), @decorator =>
add_num = decorator(add_num) def add_num(a, b): result = a + b print(result)
@return_decorator('-') def sub_num(a, b): result = a - b print(result) add_num(1
, 2) sub_num(1, 2) An effort is being made to perform the addition calculation 3 Efforts are being made to perform subtraction -1
<>9. The use of class decorators
Class decorator : Decorate existing functions with classes
class MyDecorator(object): def __init__(self, func): self.__func = func #
realization __call__ method , Indicates that the object is a callable object , It can be called like a function def __call__(self, *args, **kwargs): #
Encapsulate existing functions print(' There will be work soon ') self.__func() @MyDecorator # @MyDecorator => show =
MyDecorator(show) def show(): print(' It's going to snow ') #
implement show, It's equivalent to execution MyDecorator Class creates an instance object ,show() => object () show() There will be work soon It's going to snow
extend :
Function can be called , Because the function is implemented internally __call__ method
<>10. Application scenarios
Collects the operation or error log of a function
Verify the permissions of the function
Calculate the run time of the function
stay ORM/DB Model operation , Get the associated data dynamically through attribute method
Function data cache
Input and output of custom functions ( serialization and deserialization )
Technology