current position：Home>Python core programming - decorator
Python core programming - decorator
2022-01-30 04:39:04 【Alvin305】
Little knowledge , Great challenge ！ This article is participating in “ A programmer must have a little knowledge ” Creative activities
This article also participates in 「 Digging force Star Program 」, Win a creative gift bag , Challenge creation incentive fund
Decorator (Decorators) yes Python An important part of , In program development, we often use , Make good use of the decorator and get twice the result with half the effort . In short ： It is a function that modifies the functions of other functions . It helps keep our code short , And more Pythonic（Python aron ）.
python The decorator is essentially a function , It allows other functions to add extra functionality without any code changes , The return value of the decorator is also a function （ References to functions ） .
General understanding of decorators ：
The essence ： It's a closure function
Parameters ： The function to decorate （ Is a function name, not a function call , That is, without parentheses ）
return ： Is a decorated function （ It's also a function name, not a function call ）
effect ： Add additional functionality to existing functions without any internal modifications
characteristic ： The internal code of the function to be decorated does not need any change
1. Start with an example
A company has an employee information management system , It mainly includes adding employee information , Update employee information , Delete employee information , View employee information and other functions , Anyone can access and operate . It took some time to find out that this is not working. We should limit it , Perform login verification before each operation , Only those who have logged in can operate , The original functions are as follows ：
def add_staff(): print(' Add employee information ') def del_staff(): print(" Delete employee information ") def upd_staff(): print(" Update employee information ") def view_staff(): print(" View employee information ") Copy code
So the technical director handed the task to the small company at the same time A And small B2 personal .
Small A Is an intern who is going to graduate , Its implementation is to add verification logic to each function function , as follows ：
def add_staff(): # validate logon print(' Add employee information ') def del_staff(): # validate logon print(" Delete employee information ") def upd_staff(): # validate logon print(" Update employee information ") def view_staff(): # validate logon print(" View employee information ") Copy code
Small B He is an engineer with some working experience , His plan is , Define an additional login verification function , Then call... Respectively in the function function , as follows ：
def add_staff(): check_login() print(' Add employee information ') def del_staff(): check_login() print(" Delete employee information ") def upd_staff(): check_login() print(" Update employee information ") def view_staff() check_login(): print(" View employee information ") def check_login(): # validate logon Copy code
After completing the task, the technical director looked at the completion of the next two people , But he didn't make any comments , But a new demand , Another permission verification is required , Operation can only be carried out after verification . So small A Small B Go back and continue to modify , Small A Still add permission verification logic to each function , Small B It is still defined as a permission verification function and then called in each function function. .
Obviously , Small B The implementation of is obviously better than that of small A Of , Imagine if there are dozens of such methods , According to little A Isn't the same code to operate in the same way copy Dozens of times , Once the logic changes, it will be modified dozens of times , It's very troublesome to maintain . And small B It's much better. , Just change the check function , Then you can call it in the function function. , The efficiency is greatly improved .
But after the second round of modification , The supervisor read it and still didn't give any comments , Continue to make another demand （ Demand is changing , As a programmer, you know ）, The principle of openness and closeness is required , The internal code of the implemented function cannot be modified , But the function has to be extended . namely ：
- closed ： The implemented function code cannot be modified
- to open up ： Add other functions without changing the internal code
It's a small one A It's completely masked , I don't know where to start , And small B It's also a silly face , So small A Small B Start surfing the Internet to find all kinds of information , Finally, after several times of painstaking inquiry, Xiao B Found the answer - - Decorator
The final modified code is as follows ：
def check_login(fun): def inner(): # validate logon fun() return inner def add_staff(): print(' Add employee information ') def del_staff(): print(" Delete employee information ") def upd_staff(): print(" Update employee information ") def view_staff() print(" View employee information ") Copy code
The verification function before operation is completed without changing the internal logic , The supervisor nodded with satisfaction , Small B A raise is expected ...
3. Detailed explanation of ornaments
Alone with add_staff For example ：python The interpreter interprets the code from top to bottom , Steps are as follows ：
1） Define a closure function check_login, That is, the function check_login Load into memory
3） Definition add_staff function
On the surface, the interpreter will only interpret these sentences of code , Because the internal code of a function will not be executed before it is called . however @check_login There are many articles inside this code ,@ The function name is python A grammatical sugar in .
The above example @check_login The following operations will be performed internally ：
perform check_login function
call check_login function , And will @check_login The following function is used as check_login Parameters passed to check_login, namely @check_login Equivalent to check_login(add_staff), So it's done internally
def inner() # validate logon fun() #fun Is the parameter passed in , At this time fun Equivalent to add_staff return inner Copy code
#fun Is the parameter passed in , At this time fun Equivalent to add_staff
# The return is inner,inner It's also a function , But what is returned is not the call of the function, but the reference of the function （ Or the address of the function ） return , In fact, the original add_staff Function into another function inner in , And call in this function .
So when you want to add employees in the future , The original logic is called , The difference is that there will be a login verification before each addition . In this way, verification is performed , The original function of adding employees is implemented again , In other words, the necessary extended functions are realized without changing the original logic .
4. Decoration sequence of decorators
Let's look at a list first
# Define a function ： Complete package data def makeBold(fn): def wrapped(): return '<b>' + fn() + '</b>' return wrapped # Defined function , Complete the data package def makeItalic(fn): def wrapped(): return '<i>' + fn() + '</i>' return wrapped def test1(): return 'hello world-1' def test2(): return 'hello world-2' def test3(): return 'hello world-3' # Call function print(test1()) print(test2()) print(test3()) # Running results ： <b>hello world-1</b> <i>hello world-2</i> <b><i>hello world-3</i></b> Copy code
From the above example, we will find that ,test1 and test2 It's no different from what we said above , Other extensions are carried out before calling function functions , In this case, it is before returning a string , A package in which the string is first bold or italicized .
Next, let's focus on the third example , Here we are right test3 It was decorated twice, namely @makeBold and @makeItalic, Only from the execution order of the code, it should be carried out first makeBold Decorate and then makeItalic decorate , That is to say, call makeBold Package and then call with the returned result makeItalic Conduct < i> The parcel , Then the final result should be < i >< b >hello world-3</ b ></ i>. However, from the operation results , Contrary to what we thought , Actually, we did it first makeItalic After decoration makeBold decorate . This is the focus of this section .
namely ： When multiple decorators decorate the same function at the same time ,python The interpreter interprets from top to bottom in order , But when decorating , It starts from the decorator closest to the function and decorates from bottom to top , This is why the results we imagine are different from the actual results .
After understanding the above paragraph , We're going back to the previous Liezi , First python The interpreter explains first @makeBold Then explain @makeItalic, Then, when decorating, first carry out makeItalic Decoration, and then carry on with the results of decoration makeBold decorate , So what we see is < b>< i>hello world-3</ i></ b> instead of < i>< b>hello world-3</ b></ i>
Let's use the code to understand it step by step ：
# Define a function ： Complete package data def makeBold(fn): def wrapped(): return '<b>' + fn() + '</b>' return wrapped # Defined function , Complete the data package def makeItalic(fn): def wrapped(): return '<i>' + fn() + '</i>' return wrapped def test3(): return 'hello world-3' # The decoration steps are as follows ： First of all, test3 Conduct makeItalic decorate def test3(): return 'hello world-3' # The result after decoration can be understood as def test3(): return '<i>hello world-3</i>' # If there is only one decorator , At this point, it's over , But now multiple decorators are decorated at the same time , So in makeItalic After the decoration, there is a makeBold, So the next step is ： def test3(): return '<i>hello world-3</i>' # So finally, it goes through makeBold After decoration, the result is ：'<b><i>hello world-3</i></b>' Copy code
5. Decorated functions have parameters and return values
Sometimes we need to decorate functions with some parameters and return values , In this case, the treatment is also very simple , When defining the decorator , In the internal function of the closure function, you can declare that it has the same parameters as the decorated function , If there is a return value , Then return the decorated function .
Look at an example ：
def outer(func): def inner(a,b):# The parameters declared here are consistent with the parameters of the decorated function # Processing logic return func()# Note that here is the call of the return function , If the decorated function does not return, You don't have to go back here reutrn inner # What is returned here is the reference of the function def test(a,b): return a+b Copy code
6. Function and summary of decorator
Function execution time statistics
Preprocessing before executing a function
Clean up after function execution
Permission check and other scenarios
summary ： In general, in order to make decorators more versatile , You can define a decorator with an indefinite length parameter and a return value .
author[Alvin305],Please bring the original link to reprint, thank you.
The sidebar is recommended
- Getting started with Python - object oriented - special methods
- Using linear systems in python with scipy.linalg
- Fast power modulus Python implementation of large numbers
- Python architects recommend the book "Python programmer's Guide" which must be read by self-study Python architects. You are welcome to take it away
- Decoding the verification code of Taobao slider with Python + selenium, the road of information security
- Python game development, pyGame module, python implementation of skiing games
- Python collects and monitors system data -- psutil
- Python + selenium automated test: page object mode
- You can easily get started with Excel. Python data analysis package pandas (IV): any grouping score bar
- Python ThreadPoolExecutor restrictions_ work_ Queue size
guess what you like
Python generates and deploys verification codes with one click (Django)
[Python kaggle] pandas basic exercises in machine learning series (6)
Using linear systems in python with scipy.linalg
Using Python to realize national second-hand housing data capture + map display
How to make Python run faster? Six tips!
Python chat room (Tkinter writing interface, streaming, socket to realize private chat, group chat, check chat records, Mysql to store data)
This pandas exercise must be successfully won
[algorithm learning] sword finger offer 64 Find 1 + 2 +... + n (Java / C / C + + / Python / go / trust)
Understand Python's built-in function and add a print function yourself
Python implements JS encryption algorithm in thousands of music websites
- leetcode 35. Search Insert Position（python）
- [introduction to Python visualization]: 12 small examples of complete data visualization, taking you to play with visualization ~
- Learning this Python library can reduce at least 100 lines of code
- leetcode 67. Add Binary（python）
- Regular re parameter replacement of Python 3 interface automation test framework
- V. pandas based on Python
- Only 15 lines of code is needed for face detection! (using Python and openCV)
- [Python crawler Sao operation] you can crawl Sirius cinema movies without paying
- leetcode 69. Sqrt(x)（python）
- Teach you to read the source code of Cpython (I)
- Snowball learning started in the fourth quarter of Python. One needs three meals. I have a new understanding of Python functional programming, process-oriented, object-oriented and functional
- leetcode 88. Merge Sorted Array（python）
- Don't you know more about a python library before the end of 2021?
- Python crawler web page parsing artifact XPath quick start teaching!!!
- Use Python and OpenCV to watermark the image
- String and related methods of Python data type introduction
- Heapq module of Python module
- Introduction to beautiful soup of Python crawler weapon, detailed explanation, actual combat summary!!!
- Event loop of Python collaboration series
- Django docking pin login system
- [recalling the 1970s] using Python to repair the wonderful memories of parents' generation, black-and-white photos become color photos
- You used to know Python advanced
- Pyinstaller package Python project
- 2021 IEEE programming language rankings: Python tops the list!
- Implementation of Python automatic test control
- Python advanced: [Baidu translation reverse] graphic and video teaching!!!
- Do you know the fuzzy semantics in Python syntax?
- [Python from introduction to mastery] (XXVII) learn more about pilot!
- Playing excel office automation with Python
- Some applications of heapq module of Python module
- Python and go languages are so popular, which is more suitable for you?
- Python practical skills task segmentation
- Python simulated Login, numpy module, python simulated epidemic spread
- Python opencv contour discovery function based on image edge extraction
- Application of Hoff circle detection in Python opencv
- Python reptile test ox knife (I)
- Day 1: learn the Django framework of Python development
- django -- minio_ S3 file storage service
- [algorithm learning] 02.03 Delete intermediate nodes (Java / C / C + + / Python / go)
- Learning in Python + opencv -- extracting corners