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

How to analyze various types of decorators in Python

2025-02-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

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

This article will explain in detail how to analyze various types of Python decorators. The content of the article is of high quality, so the editor will share it for you as a reference. I hope you will have a certain understanding of the relevant knowledge after reading this article.

Decorator description

The decorator in Python is a tool that can decorate other objects. The tool is essentially a callable object (callable), so decorators can generally be implemented by functions and classes. The decorator itself needs to accept a decorated object as a parameter, which is usually a function, method, class, and so on. The decorator needs to return an object that can be a processed original parameter object, an object wrapped in and similar to the original parameter, or an irrelevant content (usually not recommended)

I believe that through the description of the above paragraph, we should be more confused! So let's use the code to understand the decorator in Python.

The simplest category of decorators: def warp (obj): return obj

That's right! This is the simplest decorator, and it is a decorator that is of no use. But it's really a decorator, and it works well. For example:

@ warp # is equivalent to foo = warp (foo) def foo (): print ('hello decorator') Foo () # = > hello decorator!

The above uses the decorator code, in fact, we can achieve the same effect in other ways. For more information, please see:

Def foo (): print ('hello decorator') Foo = warp (foo) foo () # = > hello decorator!

So, through the simplest code, we can find that the decorator actually accepts a function (object) and returns a function (callable object).

Decorator for modifying object

After understanding the meaning of the decorator, let's take a look at a slightly useful decorator. The code is as follows:

Def warp (obj): obj.name = 'python' return obj

This decorator adds only one line of code to the previous example, but it has a practical effect. Its function is to add a name attribute to the decorated object and set the value to python. The effect of this decorator is as follows:

@ warp # = > Bar = warp (Bar) class Bar (object): def _ _ init__ (self): pass print (Bar.name) # = > python

You can see that in the actual use, the warp decorator has successfully added the name attribute to the Bar object. In addition to adding properties to the class object, it can also add properties to the function object.

@ warp # = > foo = warp (foo) def foo (): pass print (foo.name) # = > python decorator for simulating objects-function decorator

The decorator in the above example modifies the incoming object directly; the most common way for the decorator is to simulate an incoming object. That is, an object similar to the original object is returned (that is, another object that is exactly the same as the calling interface), and the mock object wraps the original object. The specific code is as follows:

Def outer (func): # function decorator def inner (): func () return inner

Above is a function decorator, that is, the decorator used to decorate the function. Because it returns an inner object that simulates a func object. Here the inner object is a function, so the decorator can only decorate the function. (because inner objects can only simulate function objects such as func, not class objects)

@ outer # foo = outer (foo) def foo (): print ('hello foo') foo () # = > hello foo

The last line of foo () in the above code is essentially the executed inner (). To prove this, we can print a message in inner. And look at the _ _ name__ property of foo.

Def outer (func): # function decorator def inner (): print ('hello inner') func () return inner @ outer # foo = outer (foo) def foo (): print (' hello foo') print (foo.__name__) foo ()

The result of the above code execution is as follows:

Innerhello innerhello foo

You can see that the foo.__name__ code is printed first, notice that the content is inner rather than foo (indicating that it is essentially an inner function); secondly, when printing, first print the contents of the inner function, and then print the contents of the foo function.

A decorator for simulating objects-- class method decorator

Similar to the function decorator is the class method decorator, which has the same function and similar format. Just slightly different, here is the code for the class method decorator.

Def outer (obj): # method decorator def inner (self): print ('hello inner') obj (self) return inner class Zoo (object): def _ init__ (self): pass @ outer # = > zoo = outer (zoo) def zoo (self): print (' hello zoo') zoo = Zoo () print (zoo.zoo.__name__) zoo.zoo ()

You can see that the only difference between the class method decorator and the function decorator is that there is a default self parameter; this is because the class method itself has one more parameter than the function. The results of its implementation are as follows:

Innerhello innerhello zoo

So the last line of code, the zoo.zoo function, actually executes the inner function.

Class decorator, a decorator for simulating objects

In addition to decorating functions and methods, decorators can also decorate class objects. The specific code is as follows:

Def outer (clss): # Class decorator class Inner (object): def _ _ init__ (self): self.clss = clss () def _ getattr__ (self, attr): return getattr (self.clss) Attr) return Inner @ outer # Zoo = outer (Zoo) class Zoo (object): def _ _ init__ (self): pass def say (self): print ('hello worldview') Zoo = Zoo () print (zoo.__class__) # zoo.say () # hello world!

As you can see from the code, the class decorator is similar to the function decorator. That is, to simulate a class object that is consistent with the original parameter interface. Therefore, the decorator of the simulation class can only be used on the objects it can simulate, and can not modify other types of objects.

Decorators for special applications

All of the above are more conventional decorators, and there are other special decorators in python. For example: class static property decorator. For example, the following code:

Class Foo (object): def _ init__ (self, height, weigth): self.height = height self.weigth = weigth @ property def ratio (self): return self.height / self.weigth foo = Foo (176,120) print (foo.ratio) # = > 1.4666666666666666

The @ property decorator in the above code is a special decorator that turns the ratio method into a property. As you can see from the last call code, foo.ratio is used instead of foo.ratio ().

This kind of decorator can only be implemented with the support of specific properties and mechanisms of Python, and decorators with different characteristics need different mechanisms. The @ property decorator in the above code can be implemented using the following code.

Class Prop (object): def _ init__ (self, fget): self.fget = fget def _ get__ (self, instance, owner): return self.fget (instance)

The specific effects are as follows:

Class Foo (object): def _ init__ (self, height, weigth): self.height = height self.weigth = weigth @ Prop def ratio (self): return self.height / self.weigth foo = Foo (176,120) print (foo.ratio) # = > 1.4666666666666666

You can see that the effect is the same as the native @ property decorator.

Class implementation decorator

In the previous description of the decorator, it was said that the decorator is a callable object. In addition to functions that can implement decorators, they can also be implemented through classes. Then the specific code for the class implementation decorator is as follows:

Class Warp (object): def _ _ init__ (self): pass def _ _ call__ (self, obj): obj.name = 'warp' return obj

The function of this class decorator is also to add a name property to the incoming object and set its value to warp. The call effect is as follows:

@ Warp () def foo (): pass print (foo.name) # = > warp decorates objects with parameters / return values

In all the examples listed above, the decorated object is parameterless. If you need to decorate an object with parameters. Then you need to modify the decorator code in response. Note: this refers specifically to those analog types of decorators. That is, function decorator, class method decorator, class decorator.

Suppose we first have a function with parameters, which is as follows:

Def add (x, y): return x * y

If you use the original function decorator, you will definitely make an error. Mainly because this function takes parameters and also has a return value. The original function decorator is not supported, and the original function decorator is as follows:

Def outer (func): # function decorator def inner (): func () return inner

You can see that inner only simulates an object with no parameters and no return value. So you need to make the following changes:

Def outer (func): # function decorator def inner (x, y): print ('hello inner') return func (x, y) return inner

Such a function decorator can decorate the add function. Because the inner function adds the parameter xdepartment y, the parameter is also added when the func object is called, and the return value of the func object is returned. The specific results are as follows:

@ outerdef add (x, y): return x * y print (add (2,3)) # = > 6

Although the above code can achieve the decoration function of add, what if we now have a function with three parameters that needs decoration, or a Korean with default parameters that needs decoration. It is impossible to write a decorator with the same function for a function without a different argument. So the ultimate function decorator is written as follows:

Def outer (func): # function decorator def inner (* args, * * kwargs): print ('hello inner') return func (* args, * * kwargs) return inner

The concept of dynamic parameters in python is used so that the decorator can support functions with arbitrary combination parameters.

Decorator belt parameters

The above mentioned is the case of the modified object with parameters, and another case is that the decorator itself wants to support the parameters. This situation is similar to the reason that function modules can be more flexible by taking parameters. By adding parameters to the decorator, the function of the decorator can be made more flexible. The code is as follows:

Url_mapping = {} def route (url): def decorator (func): # function decorator url_ mapping [url] = func return func return decorator

Above is an URL route map decorator that binds different routes to different functions. If the decorator cannot take parameters, such a function cannot be achieved. The results are as follows:

@ route ('/ home') def home (): pass @ route ('/ index') def index (): pass print (url_mapping) # = > {'/ home':,'/ index':} decorator application

Python decorator is widely used, and the common processing logic of most scenes can be simplified by decorator. (using annotations similar to those in JAVA) generally common scenarios such as:

Log record

Authority verification list

Example pattern competition

Resource management

On how to carry out the analysis of various types of Python decorators to share here, I hope that the above content can be of some help to you, can learn more knowledge. If you think the article is good, you can share it for more people to see.

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