This article describes how to use Decorator in Python to simplify metaprogramming. it is from the IBM official Developer Technical Documentation. if you need Decorator, refer
Less effort and more
Decorator has something in common with the meta-programming abstraction introduced earlier in Python: even without these technologies, you can implement the functions they provide. As stated in earlier articles in the cute Python column by Michelle Simionato and I noted, even in Python 1.5, Python classes can be created, you do not need to use the meta-category hook.
The basic mediocrity of Decorator is very similar to that of Decorator. The function implemented by Decorator is to modify the functions and methods defined after Decorator. This is always possible, but this function is mainly driven by the classmethod () and staticmethod () built-in functions introduced in Python 2.2. In the old style, you can call classmethod () as follows:
Listing 1. typical "old" classmethod
class C: def foo(cls, y): print "classmethod", cls, y foo = classmethod(foo)
Although classmethod () is a built-in function, it is not unique. you can also use your own method to convert the function. For example:
Listing 2. conversion of typical "old" methods
def enhanced(meth): def new(self, y): print "I am enhanced" return meth(self, y) return newclass C: def bar(self, x): print "some method says:", x bar = enhanced(bar)
All decorator does is to avoid repeated use of the method name, and put decorator in the first place in the method definition and its name. For example:
Listing 3. typical "old" classmethod
class C: @classmethod def foo(cls, y): print "classmethod", cls, y @enhanced def bar(self, x): print "some method says:", x
The decorator can also be used for regular functions in the same way as the methods in the class. Surprisingly, all this is so simple (strictly speaking, or even unnecessary) that you only need to make simple modifications to the syntax so that everything can work better, it also makes program arguments easier. By listing multiple decorator before the function defined by the method, you can link the decorator together. good judgment can help prevent too many decorator links together, but sometimes it makes sense to link several decorator together:
Listing 4. link decorator
@synchronized@loggingdef myfunc(arg1, arg2, ...): # ...do something# decorators are equivalent to ending with:# myfunc = synchronized(logging(myfunc))# Nested in that declaration order
Decorator is just a syntactic sugar. if you are too eager, it will cause you to take a rock and drop your feet. Decorator is actually a function with at least one parameter. the programmer is responsible for ensuring that the returned content of decorator is still a meaningful function or method, in addition, the original functions are implemented to make the connection useful. For example, here are two incorrect decorator usage:
Listing 5. the error decorator does not return a function
>>> def spamdef(fn):... print "spam, spam, spam"...>>> @spamdef... def useful(a, b):... print a**2 + b**2...spam, spam, spam>>> useful(3, 4)Traceback (most recent call last): File "
", line 1, in ?TypeError: 'NoneType' object is not callable
The decorator may return a function, but there is no meaningful association between the function and the undecorated function:
Listing 6. ignore the decorator of the input function
>>> def spamrun(fn):... def sayspam(*args):... print "spam, spam, spam"... return sayspam...>>> @spamrun... def useful(a, b):... print a**2 + b**2...>>> useful(3,4)spam, spam, spam
Finally, a better-performing decorator can enhance or modify unmodified functions in some ways:
Listing 7. modify the decorator of unmodified function behavior
>>> def addspam(fn):... def new(*args):... print "spam, spam, spam"... return fn(*args)... return new...>>> @addspam... def useful(a, b):... print a**2 + b**2...>>> useful(3,4)spam, spam, spam25
You may question how useful () is? Is addspam () really such an outstanding enhancement? However, this mechanism is at least consistent with the pattern that you normally see in useful decorator.
Introduction to Advanced abstraction
Based on my experience, the most common use cases of meta-classes are to modify methods in the class after class instantiation. Currently, decorator does not allow you to modify the class instantiation itself, but they can modify the methods attached to the class. This does not allow you to dynamically add or delete methods or class attributes during the instantiation process, but it allows these methods to change their behavior according to the environment conditions at runtime. In terms of technology, decorator is applied when running class statements. for top-level classes, decorator is closer to "compile-time" rather than "runtime ". However, it is as simple as creating a class factory to arrange the runtime decision of decorator. For example:
Listing 8. robust but deeply nested decorator
def arg_sayer(what): def what_sayer(meth): def new(self, *args, **kws): print what return meth(self, *args, **kws) return new return what_sayer