In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-05 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains the "python decorator principle and case analysis", the content of the article is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "python decorator principle and case analysis" bar!
Catalogue
Preface
What is a decorator
Second, why to use decorator
3. Simple decorator
Fourth, the grammar sugar of the decorator
Fifth, the decorator transmits parameters
VI. Decorator with parameters
Class decorator
Class decorator with parameters
IX. The order of decorators
Preface
Recently, when someone asked me what the decorator is, I told him that it is actually a decorator that is similar to a girl's hairpin. A girl you like can have many hairpins, and when she wears different hairpins, different hairpins are decorated on the top of her head. But the girl you like is still the girl you like. If you still don't understand, the decorator is our mobile phone case. although you put on the mobile phone case, it does not affect the function of your mobile phone, but your mobile phone should still be able to play for you, make phone calls, play games and play games. The blog of the collection of siege lion Baiyu collects the blog of siege lion Baiyu. And your phone becomes a phone with a cell phone case.
The decorator is an obstacle in the way of python. Whether you do it or not, it's all there. If you want to learn the advanced use of python, the decorator is a tiger that Wu Song must knock down.
The environment of this paper is as follows:
Win10
Python3.7
What is a decorator
The decorator adds a new small function to the existing module, and it can expand the function of the original function, and it does not need to modify the content of the original function or modify the call of the original function.
The use of decorators conforms to the open and closed principle of object-oriented programming.
The principle of opening and closing is mainly embodied in two aspects:
Being open to extension means that when there are new requirements or changes, existing code can be extended to adapt to the new situation.
Closing to modifications means that once the class is designed, it can work independently without making any changes to the class.
Second, why to use decorator
Before using the decorator, we need to know that in python, everything is an object, that is, everything can be passed on.
A function can also be passed as an argument to a function.
Through the following simple example, you can see more intuitively how the function name is passed directly as a parameter.
Def baiyu (): print ("I am the siege lion Baiyu") def blog (name): print ('enter the blog function') name () print ('my blog is https://blog.csdn.net/zhh763984017') if _ _ name__ = ='_ main__': func = baiyu # here is to assign the function name baiyu to the variable func func () # execute the func function print ( '-') blog (baiyu) # pass the function baiyu as an argument to the blog function
The execution result is as follows:
Next, I want to know the execution time of the baiyu and blog functions, respectively, so I modify the code as follows:
Import time def baiyu (): T1 = time.time () print ("I am a siege lion white jade") time.sleep (2) print ("execution time is:", time.time ()-T1) def blog (name): T1 = time.time () print ('enter blog function') name () print ('my blog is https://blog.csdn.net/zhh763984017') print ("execution time is:" Time.time ()-T1) if _ _ name__ = ='_ _ main__': func = baiyu # here the function name baiyu is assigned to the variable func func () # execute the func function print ('-') blog (baiyu) # pass the baiyu function as an argument to the blog function
The above rewrite has achieved the functionality I need, but when I have another new function [python_blog_list], the details are as follows:
Def python_blog_list (): print (''[Python] crawler actual combat, zero basic initial test crawler download picture (with source code and analysis process) https://blog.csdn.net/zhh763984017/article/details/119063252') print (''[Python] except for multithreading and multiprocess You will also be able to cooperate with https://blog.csdn.net/zhh763984017/article/details/118958668'') print (''[Python] crawler speed tips, multi-thread and multi-process (attached source code example) https://blog.csdn.net/zhh763984017/article/details/118773313'') print (''[Python] crawler parsing sharp weapon Xpath Quick mastery from shallow to deep (with source code example) https://blog.csdn.net/zhh763984017/article/details/118634945')
If you also need to calculate the execution time of the function, according to the previous logic, it is rewritten as follows:
Def python_blog_list (): T1 = time.time () print (''[Python] crawler, zero-based initial crawler downloads pictures (with source code and analysis process) https://blog.csdn.net/zhh763984017/article/details/119063252') print (''[Python] except for multithreading and multiprocess You will also be able to cooperate with https://blog.csdn.net/zhh763984017/article/details/118958668'') print (''[Python] crawler speed tips, multi-thread and multi-process (attached source code example) https://blog.csdn.net/zhh763984017/article/details/118773313'') print (''[Python] crawler parsing sharp weapon Xpath Quickly master (with source code example) https://blog.csdn.net/zhh763984017/article/details/118634945'') print ("execution time is:", time.time ()-T1)
If you want to write in this way, won't you repeat the wheel? Although human nature is pigeon king and repeater, as an excellent cv engineer (ctrl+c and ctrl+v), we must find a way to be lazy.
The decorator allows us to expand some functions that the original function does not have.
3. Simple decorator
Based on the above function execution time requirements, we will handwrite a simple decorator for implementation.
Import time def baiyu (): print ("I am the siege lion Baiyu") time.sleep (2) def count_time (func): def wrapper (): T1 = time.time () func () print ("execution time is:" Time.time ()-T1) return wrapper if _ _ name__ = ='_ main__': baiyu = count_time (baiyu) # because the time function object wrapper returned by the decorator count_time (baiyu) This statement is equivalent to baiyu = wrapper baiyu () # executing baiyu () is equivalent to executing wrapper ()
Count_time here is a decorator, the decorator function defines a wrapper function, the func function as a parameter input, the function is to achieve the function is to wrap the func, and return wrapper function. The body of the wrapper function is to implement the contents of the decorator.
Of course, the wrapper function name here can be customized, as long as the function name you define is the same as the function name of your return.
Fourth, the grammar sugar of the decorator
If you look at the code in other python projects, you will inevitably see the @ symbol, which is the syntax candy of the decorator. Therefore, the above simple decorator can be implemented through syntax sugar, so that it can be saved.
Baiyu = count_time (baiyu)
This line of code, and directly call the function baiyu ()
In other words, what actually uses the decorator is that the parameter passed in by default is the decorated function.
Import timedef count_time (func): def wrapper (): T1 = time.time () func () print ("execution time is:" Time.time ()-T1) return wrapper @ count_timedef baiyu (): print ("I am the siege lion Baiyu") time.sleep (2) if _ _ name__ = ='_ _ main__': # baiyu = count_time (baiyu) # because the time function object wrapper returned by the decorator count_time (baiyu) This statement is equivalent to baiyu = wrapper # baiyu () # executing baiyu () is equivalent to executing wrapper () baiyu () # after the grammatical sugar, you can call this function directly.
When our decorated function takes arguments, how do we write the decorator?
Above we have defined a blog function that takes parameters.
Def blog (name): print ('enter the blog function') name () print ('my blog is https://blog.csdn.net/zhh763984017')
At this point, our decorator function needs to be optimized and modified into a decorator that can accept arbitrary parameters.
Def count_time (func): def wrapper (* args,**kwargs): T1 = time.time () func (* args,**kwargs) print ("execution time is:", time.time ()-T1) return wrapper
Here, the arguments of our wrapper function are * args and * * kwargs, which means that any parameter is acceptable.
At this point we can call our decorator.
Import timedef count_time (func): def wrapper (* args, * * kwargs): T1 = time.time () func (* args, * * kwargs) print ("execution time is:" Time.time ()-T1) return wrapper@count_timedef blog (name): print ('enter blog function') name () print ('my blog is https://blog.csdn.net/zhh763984017') if _ _ name__ = ='_ _ main__': # baiyu = count_time (baiyu) # because the decorator count_time (baiyu) returns the time function object wrapper This statement is equivalent to baiyu = wrapper # baiyu () # executing baiyu () is equivalent to executing wrapper () # baiyu () # grammatical sugar, you can call this function directly. Blog (baiyu) VI. Decorator with parameters
As we know earlier, the decorator function is also a function, since it is a function, then we can pass parameters, how do we write a decorator with parameters?
Our decorator just implements a count, so I want to pass in some remarks msg information when using the decorator, what should I do? Let's take a look at the following code
Import timedef count_time_args (msg=None): def count_time (func): def wrapper (* args, * * kwargs): T1 = time.time () func (* args, * * kwargs) print (f "[{msg}] execution time is:" Time.time ()-T1) return wrapper return count_time@count_time_args (msg= "baiyu") def fun_one (): time.sleep (1) @ count_time_args (msg= "zhh") def fun_two (): time.sleep (1) @ count_time_args (msg= "mylove") def fun_three (): time.sleep (1) if _ _ name__ = ='_ main__': Fun_one () fun_two () fun_three ()
Based on the original count_time function, we wrap a layer of count_time_args that is used to receive parameters, and the received parameters can be called directly in the internal function. The execution effect of the above code is as follows:
Class decorator
Above we learned how to write decorator functions, in python, in fact, can also be similar to achieve the decorator function, called class decorator. The implementation of the class decorator calls the _ _ call__ function in the class. The class decorator is written more simply than our decorator function.
When we use the class as a decorator, the workflow:
Initialize the class with the _ _ init__ () method
Call the real decoration method through the _ _ call__ () method
Import timeclass BaiyuDecorator: def _ init__ (self, func): self.func = func print ("execute the _ _ init__ method of the class") def _ _ call__ (self, * args, * * kwargs): print ('enter the _ _ call__ function') T1 = time.time () self.func (* args, * * kwargs) print ("execution time is:" Time.time ()-T1) @ BaiyuDecoratordef baiyu (): print ("I am the White Jade of the siege Lion") time.sleep (2) def python_blog_list (): time.sleep (5) print (''[Python]) Crawler Zero-basic initial test crawler download picture (with source code and analysis process) https://blog.csdn.net/zhh763984017/article/details/119063252') print (''[Python] in addition to multi-thread and multi-process, you also need to cooperate with https://blog.csdn.net/zhh763984017/article/details/118958668') print (''[Python] crawler speed tips) Multi-thread and multi-process (with source code example) https://blog.csdn.net/zhh763984017/article/details/118773313'') print (''[Python] crawler parsing sharp weapon Xpath Quickly master (with source code example) https://blog.csdn.net/zhh763984017/article/details/118634945'') @ BaiyuDecoratordef blog (name): print ('enter blog function') name () print ('my blog is https://blog.csdn.net/zhh763984017') if _ _ name__ = ='_ main__': baiyu () print ('- -') blog (python_blog_list)
Class decorator with parameters
When the decorator has arguments, the _ _ init__ () function cannot be passed into func (func represents the function to be decorated), while func is passed in when the _ _ call__ function is called.
Class BaiyuDecorator: def _ init__ (self, arg1, arg2): # init () the parameters in the method are all decorator parameters print ('execute _ _ init__ () method like Decorator') self.arg1 = arg1 self.arg2 = arg2 def _ call__ (self, func): # because the decorator takes parameters So the location to receive incoming function variables is here print ('execute the _ _ call__ () method of class Decorator') def baiyu_warp (* args): # here the function name of the decorator can be named at will You can print ('execute wrap ()') print ('decorator parameters:', self.arg1, self.arg2) print ('execute' + func.__name__ +'()') func (* args) print (func.__name__ +'() finished') return baiyu_warp @ BaiyuDecorator ('Hello'') as long as it is the same as the function name of func.__name__ 'Baiyu') def example (A1, a2, A3): print (' parameters passed in example ():', A1, a2, A3) if _ _ name__ = ='_ _ main__': print ('ready to call example ()') example ('Baiyu',' Happy', 'Coder') print (' test code execution completed')
It is recommended that students compare the difference between the code here and the decorator code without parameters to deepen their understanding.
IX. The order of decorators
A function can be decorated by multiple decorators, so what is the order in which the decorators are executed? Let's execute the following code to make it clear.
Def BaiyuDecorator_1 (func): def wrapper (* args, * * kwargs): func (* args, * * kwargs) print ('I am decorator 1') return wrapper def BaiyuDecorator_2 (func): def wrapper (* args, * * kwargs): func (* args, * * kwargs) print ('I am decorator 2') return wrapper def BaiyuDecorator_3 (func): def wrapper (* args) * * kwargs): func (* args, * * kwargs) print ('I am the decorator 3') return wrapper @ BaiyuDecorator_1@BaiyuDecorator_2@BaiyuDecorator_3def baiyu (): print ("I am the white jade of the siege lion") if _ _ name__ = ='_ main__': baiyu ()
As can be seen from the output, the function decorated by the decorator first executes the function of the original function, and then executes the contents of the decorator from the inside to the outside.
The code for our function with three decorators is as follows:
@ BaiyuDecorator_1@BaiyuDecorator_2@BaiyuDecorator_3def baiyu (): print ("I am the siege lion Baiyu")
The above code can be thought of as the following code to understand why it is executed from the inside out
Baiyu = BaiyuDecorator_1 (BaiyuDecorator_2 (BaiyuDecorator_3 (baiyu)
Thank you for your reading, the above is the content of "the principle and case analysis of python decorator". After the study of this article, I believe you have a deeper understanding of the principle and case analysis of python decorator, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.