Analyze the key points of the Decorator pattern in the Python design pattern, pythondecorator

Source: Internet
Author: User

Analyze the key points of the Decorator pattern in the Python design pattern, pythondecorator

First, a four-person group defines the Decorator mode: dynamically adds some additional responsibilities to an object.
Let's talk about the advantages of this mode: authentication, permission check, logging, checking parameters, locking, and so on. These functions are irrelevant to the system business, but are required by the system, to be more clear, we need to understand the Aspect-oriented programming (AOP ).
In Python, the Decorator mode can be implemented in a way similar to other programming languages such as C ++ and Java. However, Python has far more capabilities in terms of application decoration concepts, python provides a syntax and a programming feature to enhance this feature. The syntax provided by Python is the decorator syntax, as follows:

@aoodef foo(): passdef aoo(fn):  return fn

The decoration mode emphasizes dynamically adding additional features to the object. Python has many built-in support for the decorator, so it is very easy to use the decorator mode in Python. Below is a typical example to add the log function:

Import functoolsdef log_wrapper (fun): @ functools. wraps (fun) def wrapper (* args, ** kwargs): print 'add the log before function execution 'ret = fun (* args, ** kwargs) print 'Return ret return wrapper @ log_wrapperdef test (): print 'hello, world'

Functools. wraps is a special decoration tool provided by the Python standard library. It is used to solve some common problems caused by the decoration tool, such as inconsistent function names and doc. @ Is a syntactic sugar provided by Python for the decorator. The above @ log_wrapper is equivalent to wrap_test = log_rapper (test). After @ is used, this step is done by the interpreter.

The decorator is a required skill in Python programming and is often used in the coding process.

Here is just a common embedded Function

def foo(x):  y = x  def foo1 ():    a = 1    return a  return foo1

The boo below is a closure.

def aoo(a, b):  c = a  def boo (x):    x = b + 1    return x  return boo

The special feature of boo is that it references the external variable B. When an aoo returns, as long as the return value (boo) persists, the reference to B will always exist.
The above knowledge may take some time to digest. If you think you have mastered this knowledge, let's go back to the question and see how these language features implement the concept of decoration in Python.
Let's take a look at a simple example and then go deeper. This example shows how to implement the lock function?
The specific requirement is as follows: I have an object that implements some functions and provides some interfaces for other modules to call. This object runs in a concurrent environment, therefore, I need to synchronize interface calls. The first version of the Code is as follows:

class Foo(object):  def __init__(self, …):    self.lock = threading.Lock()  def interface1(self, …):    self.lock.acquire()    try:     do something    finally:     self.lock.release()  def interface2(self, …):    same as interface1()  …

This version of the Code has obvious problems, that is, each interface function has the same lock/unlock code. Repeated Code leads to more typing and reading, for more maintenance and modifications, the most important thing is that the programmer's focus on the business is dispersed, the real business code starts at two indentations from the function definition, even if your monitor is a wide screen, it will bring some reading difficulties.
You intuitively think that the code can be incorporated into a function for reuse, but note that the code is not a complete code block, instead, the Business Code is embedded in the middle.
Now we use the decorator syntax to improve this part of code and get the 2nd version code:

def sync(func): def wrapper(*args, **kv):   self = args[0]   self.lock.acquire()   try:    return func(*args, **kv)   finally:    self.lock.release() return wrapperclass Foo(object):  def __init__(self, …):    self.lock = threading.Lock()  @sync  def interface1(self, …):    do something  @sync  def interface2(self, …):    do something  …

The first parameter of a decorator function is the function object to be decorated, and the decorator function must return a function object. For example, in the sync function, when interface1 is decorated, the value of func is interface1, and the returned value is wrapper. However, when interface1 of the Foo-like instance is called, the wrapper function is actually called, in the wrapper function body, the actual interface1 is indirectly called. When interface2 is called, the wrapper function is also called. However, since func has become interface2 during decoration, therefore, the actual interface2 function is indirectly called.
Benefits of using the decorator Syntax:
The amount of code is greatly reduced. Less code means less maintenance, less reading, and less typing, which is advantageous (reusable and maintainable)
Most of the user's focus is on the Business Code, and the code of addition and subtraction locks is missing, which improves readability.
Disadvantages:
The Business Object Foo has a non-business data member lock, which is very eye-catching;
A considerable degree of coupling, the first parameter of wrapper must be the object itself, and a lock object must exist in the decorated object, which adds restrictions to the customer object, it is not very comfortable to use.
Let's think about it further:
Must the lock object be placed in Foo?
Typing @ sync for each interface function is still annoying and repetitive. If one is missing, it will still cause inexplicable runtime errors. Why not concentrate on it?
To solve the preceding disadvantages, the code for version 3rd is as follows:

class DecorateClass(object): def decorate(self):  for name, fn in self.iter():   if not self.filter(name, fn):    continue   self.operate(name, fn)class LockerDecorator(DecorateClass): def __init__(self, obj, lock = threading.RLock()):  self.obj = obj  self.lock = lock def iter(self):  return [(name, getattr(self.obj, name)) for name in dir(self.obj)] def filter(self, name, fn):  if not name.startswith('_') and callable(fn):    return True  else:    return False def operate(self, name, fn):  def locker(*args, **kv):   self.lock.acquire()   try:    return fn(*args, **kv)   finally:    self.lock.release()  setattr(self.obj, name, locker)class Foo(object):  def __init__(self, …):    …    LockerDecorator(self).decorate()  def interface1(self, …):    do something  def interface2(self, …):    do something  …

The decoration of object functions is a more general function. It is not limited to locking interfaces. I use two classes to complete this function. DecorateClass is a base class, only template method is defined to traverse and apply the decoration function. LockerDecorator locks the object. iter is the iterator, defines how to traverse the members (including data members and member functions) in the object. filter is a filter and defines the members that comply with the Rules to become an interface. operate is the execution function, the object interface lock function is specifically implemented.
In the _ init _ function of the business class Foo, you only need to add the last line of code: LockerDecorator (self). decorate () to complete the object lock function.
If the interfaces provided by your object are special, you can simply rewrite the filter or inherit the LockerDecorator and overwrite the filter. In addition, if you want to use other decorative functions, you can write a class inherited from DecorateClass and implement the iter, filter, and operate functions.

Articles you may be interested in:
  • Measure the test taker's knowledge about the observer mode and Strategy Mode in Python Design Mode Programming.
  • Simple program example of interpreter mode in Python Design Mode Programming
  • An example of how to use the design pattern in Python
  • Instance parsing Python Design Mode Programming-Application of Bridge Mode
  • Examples of Adapter mode in Python Design Mode Programming
  • Application Example of prototype in design mode in Python Program
  • In-depth analysis of the use of builder mode in Python Design Mode Programming
  • An example of how to use the abstract factory mode in Python Design Mode Programming
  • The example explains how to use the factory method mode of programming in Python design mode.
  • Detailed description of the use of the factory method mode in the design mode in the Python Program
  • Use the simple factory mode for Python Design Mode Programming
  • Example of using the responsibility chain mode and iterator mode in the design mode in Python

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.