Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Analysis on the use of python decorator

2025-01-14 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

Most people do not understand the knowledge points of this article "case analysis of the use of python decorator", so the editor summarizes the following contents, detailed contents, clear steps, and has a certain reference value. I hope you can get something after reading this article. Let's take a look at this "case analysis of the use of python decorator" article.

First, the use scene of the decorator

It is often used in scenarios with faceted requirements, such as log insertion, performance testing, transaction processing, caching, permission verification, and so on. Decorators are an excellent design for solving such problems, and with decorators, we can extract a lot of similar code that has nothing to do with the function itself and continue to reuse.

In a nutshell, the role of the decorator is to add additional functionality to existing objects.

Second, why do you need decorators

1. First, let's take a look at a simple example: def foo (): print ('i am foo') 2. Increase demand.

Now there is a new requirement that you want to record the execution log of the function, so add the log code to the code:

Def foo (): print ('i am foo') print ("foo is running") 3, there is another demand

Suppose there are 100 functions that need to increase this requirement, and then there may be an increase in the need to print logs before execution for all 100 functions. Do you want to change it one by one?

Of course not, this will result in a lot of identical code, to reduce rewriting code, we can do this, redefine a function: specifically process the log, and then execute the real business code after the log processing.

Def use_logging (func): print ("% s is running"% func.__name__) func () def bar (): print ('I am bar') use_logging (bar) result: # bar is running#i am bar

The function use_logging is the decorator, which wraps the func that executes the real business method in the function, which looks like bar is decorated by use_logging. In this example, when a function enters and exits, it is called a cross section (Aspect), and this kind of programming is called aspect-oriented programming (Aspect-Oriented Programming).

Through the above use_logging function we have added the log function, no matter how many functions need to add logs or modify the format of the log, we only need to modify the use_logging function and execute use_logging (decorated function) to achieve the desired effect.

Def use_logging (func): print ("% s is running"% func.__name__) return func@use_loggingdef bar (): print ('I am bar') bar () 3. Introduction to basic decorator

1. Decorator grammar sugar

Python provides the @ symbol as the syntax sugar of the decorator, which makes it easier for us to apply the decoration function; but the use of syntax sugar requires that the decoration function must return a function object. So we wrap the above func function with an embedded function and return it.

The decorator is equivalent to executing the decorated function use_loggin and then returning the decorated function bar, so when bar () is called, it is equivalent to executing two functions. Equivalent to use_logging (bar) ()

Def use_logging (func): def _ deco (): print ("% s is running"% func.__name__) func () return _ deco@use_loggingdef bar (): print ('I am bar') bar () 2, decorate the function with parameters

Now we need to pass in two parameters and calculate the value, so we need to change the inner function and pass in our two parameters an and b, which are equivalent to use_logging (bar) (1line 2).

Def use_logging (func): def _ deco (aMagneb): print ("% s is running"% func.__name__) func (amemb) return _ deco@use_loggingdef bar (amemb): print ('I am bar:%s'% (axib)) bar (1Person2)

The function we decorate may have different arguments and types. Do we need to modify the decorator each time? This is of course unscientific, so we use the variable length parameters * args and * * kwargs of python to solve our parameter problem.

3. The number of function parameters is uncertain.

Without the parameter decorator version, this format is suitable for decorators without parameters.

After the following modifications, we have adapted to various lengths and types of parameters. This version of the decorator can be decorated with any type of no-argument function.

Def use_logging (func): def _ deco (* args,**kwargs): print ("% s is running"% func.__name__) func (* args,**kwargs) return _ deco@use_loggingdef bar (a deco@use_loggingdef bar b): print ('I am bar:%s'% (aforb)) @ use_loggingdef foo (a dagger b): print ('I am bar:%s'% (a+b+c)) bar (1) foo (1) 3) 4. Decorator belt parameters

Decorator with parameters, this format is suitable for decorators with parameters.

In some cases we need to get the decorator with parameters, so we need to write a higher-order function that returns a decorator, which is more complicated to write. For example:

#! / usr/bin/env python#-*-coding:utf-8-*-# _ _ author__ = "TKQ" def use_logging (level): def _ deco (func): def _ deco (* args, * * kwargs): if level = = "warn": print "% s is running"% func.__name__ return func (* args * * kwargs) return _ _ deco return _ deco@use_logging (level= "warn") def bar (an am bar:%s'% b): print ('i am bar:%s'% (aquib)) bar (1m 3) # is equivalent to use_logging (level= "warn") (bar) (1m 3) 5, functools.wraps

Using the decorator greatly reuses the code, but one of its disadvantages is that the meta-information of the original function is missing, such as docstring, _ _ name__, and parameter list of the function. Let's take a look at the example:

Def use_logging (func): def _ deco (* args,**kwargs): print ("% s is running"% func.__name__) func (* args,**kwargs) return _ deco@use_loggingdef bar (): print ('i am bar') print (bar.__name__) bar () # bar is running#i am bar#_deco# function name becomes _ deco instead of bar This situation can cause problems when using the reflection feature. Therefore, functools.wraps is introduced to solve this problem.

Use functools.wraps:

Import functoolsdef use_logging (func): @ functools.wraps (func) def _ deco (* args,**kwargs): print ("% s is running"% func.__name__) func (* args,**kwargs) return _ deco@use_loggingdef bar (): print ('i am bar') print (bar.__name__) bar () # result:#bar is running#i am bar#bar, this is the result we want. OK! 6. Implement adaptive import functoolsdef use_logging (arg) of decorator with and without parameters: if callable (arg): # determine whether the parameter is a function The decorator with no parameters calls this branch @ functools.wraps (arg) def _ deco (* args,**kwargs): print ("% s is running"% arg.__name__) arg (* args) * * kwargs) return _ deco else:# decorator calls this branch def _ deco (func): @ functools.wraps (func) def _ _ deco (* args, * * kwargs): if arg = = "warn": print "warn%s is running"% func.__name__ return func (* args) * * kwargs) return _ _ deco return _ deco@use_logging ("warn") # @ use_loggingdef bar (): print ('I am bar') print (bar.__name__) bar () 3. Class decorator

Using class decorator can achieve the effect of parameter decorator, but the implementation is more elegant and concise, and can be flexibly extended through inheritance.

1. Class decorator class loging (object): def _ init__ (self,level= "warn"): self.level = level def _ call__ (self,func): @ functools.wraps (func) def _ deco (* args, * kwargs): if self.level = = "warn": self.notify (func) return func (* args) * * kwargs) return _ deco def notify (self,func): # logit logs only Don't do anything else print "% s is running"% func.__name__@loging (level= "warn") # execute the _ _ call__ method def bar (def bar b): print ('I am bar:%s'% (aquib)) bar (1) 3) 2, inheritance extension class decorator class email_loging (Loging):''an implementation version of loging You can send email to the administrator''def _ _ init__ (self, email='admin@myproject.com', * args, * * kwargs) when the function is called: self.email = email super (email_loging, self). _ _ init__ (* args, * * kwargs) def notify (self) Func): # send an email to self.email print "% s is running"% func.__name__ print "sending email to% s"% self.email@email_loging (level= "warn") def bar (an am bar:%s'% b): print ('I am bar:%s'% (aquib)) bar (1) above is about the article "Analysis of the use of python decorators" I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please pay attention to the industry information channel.

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.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report