Home > Backend Development > Python Tutorial > Detailed explanation of the concise guide to using the descriptor descriptor in Python

Detailed explanation of the concise guide to using the descriptor descriptor in Python

高洛峰
Release: 2017-03-03 15:53:38
Original
1416 people have browsed it

Descriptor is mainly used to define methods and attributes in Python, and its use is quite technical. Here we will start from the basics and compile a concise guide to the use of descriptor descriptors in Python

When defining an iterator, the description is an object that implements the iteration protocol, that is, an object that implements the __iter__ method. In the same way, the so-called descriptor is an object that implements the descriptor protocol, that is, the __get__, __set__, and __delete__ methods.

Looking at the definition alone, it is quite abstract. talk is cheap. Look at the code:

class WebFramework(object):
  def __init__(self, name='Flask'):
    self.name = name

  def __get__(self, instance, owner):
    return self.name

  def __set__(self, instance, value):
    self.name = value


class PythonSite(object):

  webframework = WebFramework()

In [1]: PythonSite.webframework
Out[1]: 'Flask'

In [2]: PythonSite.webframework = 'Tornado'

In [3]: PythonSite.webframework
Out[3]: 'Tornado'
Copy after login

defines a class WebFramework, which implements the descriptor protocols __get__ and __set__. The object (class is also an object, everything are objects) becomes a descriptor. Implementing both __get__ and __set__ is called a data descriptor. Those that only implement __get__ are non-descriptors. The difference between the two is the priority of the dictionary relative to the instance.

If there is an attribute with the same name as the descriptor in the instance dictionary, if the descriptor is a data descriptor, the data descriptor will be used first. If it is a non-data descriptor, the attributes in the dictionary will be used first.

Call of descriptor
For this type of magic, the calling method is often not used directly. For example, decorators need to be called with the @ symbol. Iterators are usually used during iteration, or using the next method call. The descriptor is relatively simple and will be called when object attributes are set.

In [15]: webframework = WebFramework()

In [16]: webframework.__get__(webframework, WebFramework)
Out[16]: 'Flask'
Copy after login

Application of descriptor
The role of descriptor is mainly in the definition of methods and attributes. Since we can re-describe the properties of a class, this magic can change some behaviors of the class. The simplest application is to use a decorator to write a cache of class attributes. The author of Flask wrote a werkzeug network tool library, which uses the characteristics of the descriptor to implement a cache.

class _Missing(object):
  def __repr__(self):
    return 'no value'

  def __reduce__(self):
    return '_missing'


_missing = _Missing()


class cached_property(object):
  def __init__(self, func, name=None, doc=None):
    self.__name__ = name or func.__name__
    self.__module__ = func.__module__
    self.__doc__ = doc or func.__doc__
    self.func = func

  def __get__(self, obj, type=None):
    if obj is None:
      return self
    value = obj.__dict__.get(self.__name__, _missing)
    if value is _missing:
      value = self.func(obj)
      obj.__dict__[self.__name__] = value
    return value


class Foo(object):
  @cached_property
  def foo(self):
    print 'first calculate'
    result = 'this is result'
    return result


f = Foo()

print f.foo  # first calculate this is result
print f.foo  # this is result
Copy after login

The running results are visible. First calculate only caches the results after it is calculated during the first call. The advantage of this is that in network programming, when parsing the HTTP protocol, the HTTP header is usually parsed into a dictionary of python. When using the view function, this header may be accessed at one time, so this header is used as a descriptor. Caching can reduce redundant parsing.

Descriptors are widely used in python, and are usually used together with decorators. With great magic comes great responsibility. Descriptors can also be used to implement "pre-compilation" of SQL statements in ORM. Proper use of descriptors can make your Python code more elegant.

For more detailed explanations of the concise guide to using the descriptor descriptor in Python, please pay attention to the PHP Chinese website for related articles!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template