A tutorial on using decorator in Python to simplify metaprogramming _python

Source: Internet
Author: User

Less labor, more.

Decorator has something in common with the metaprogramming abstractions introduced before Python: Even without these technologies, you can implement the functionality they provide. As Michele Simionato and I pointed out in an earlier article in the lovely Python column, even in Python 1.5, the creation of a Python class is possible without the need for a "meta-class" hook.

Decorator is fundamentally mediocre and very similar. The function implemented by decorator is to modify the functions and methods defined immediately after decorator. This is always possible, but this functionality is primarily 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-fashioned" 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 methods to transform functions. For example:
Listing 2. Conversion of a typical "legacy" method

def enhanced (Meth):
  def new (self, y):
    print "I am Enhanced" return
    meth (self, y) return
  new
class C:
  def bar (self, x):
    print "Some method says:", x
  bar = Enhanced (bar)

What decorator does is prevent you from reusing the method name, and place the decorator where it is first mentioned in the method definition and its name. For example:
Listing 3. Typical "old-fashioned" classmethod

Class C:
  @classmethod
  def foo (cls, y):
    print "Classmethod", cls, y
  @enhanced
  def bar (self, x):
    print "Some method says:", X

Decorator can also be used with regular functions in the same way as methods in a class. Surprisingly, it's so simple (strictly, even unnecessary) to simply change the syntax, everything will work better, and make the program's argument easier. Decorator can be linked together by listing multiple decorator before the function-defined functions; good judgment helps prevent too many decorator to be linked together, but sometimes it makes sense to link several decorator together:
Listing 4. Link Decorator

@synchronized
@logging
def myfunc (arg1, Arg2, ...): # ... do
  something
# decorators are to Ending with:
#  MyFunc = synchronized (logging (myfunc))
# Nested in ' that Declaration order

Decorator is just a grammar candy, if you are too anxious, then it will cause you to lift a stone to hit your own foot. Decorator is actually a function with at least one parameter--the programmer is responsible for ensuring that the return content of decorator is still a meaningful function or method, and implements the original function to make the connection useful. For example, here is the decorator two incorrect usage:
Listing 5. Error without return function decorator

>>> 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 ' <stdin> ', line 1 , in?
TypeError: ' Nonetype ' object is not callable

Decorator may return a function, but there is no meaningful association between this function and the unmodified function:
Listing 6. Ignore decorator of incoming functions

>>> 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 the operations of unmodified functions in some ways:
Listing 7. Modifying 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, spam
25

You may question how useful useful () really is. Addspam () is it really that great enhancement? But this mechanism is at least in line with the pattern you can usually see in useful decorator.

Introduction to Advanced Abstraction

According to my experience, the most common application of the meta class is to modify the methods in the class after the class is instantiated. Decorator currently 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 Remove method or class properties during the instantiation process, but it allows these methods to change their behavior at run time based on the conditions of the environment. Now technically, decorator is applied when the class statement is run, and for the top-level class it is closer to "compile time" than "runtime." However, scheduling decorator Run-time decisions is as simple as creating a class factory. 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 to
    new return
  What_sayer

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.