[Reprinted] Python descriptor introduction, reprinted python character Introduction

Source: Internet
Author: User

[Reprinted] Python descriptor introduction, reprinted python character Introduction

Source: Alex Starostin

Link: www.ibm.com/developerworks/cn/opensource/ospythondescriptors/

For Python @ modifier articles, refer to: https://my.oschina.net/shyl/blog/637990,

Introduction

Python 2.2 introduces Python descriptors and some new style classes, but they are not widely used. Python descriptor is a method for creating managed properties. In addition to other advantages, managed properties are also used to protect attributes from being modified or to automatically update the value of a dependency property.

Descriptors increase understanding of Python and improve coding skills. This article introduces the descriptor protocol and demonstrates how to create and use descriptors.

Descriptor Protocol

The Python descriptor protocol is only a method that specifies the event to occur when attributes are referenced in the model. It allows programmers to easily and effectively manage attribute access:

1. set 2, get 3, and delete

In other programming languages, descriptors are called setter and getter, while common functions are used to Get and Set a private variable. Python does not have the concept of private variables, and the descriptor protocol can be used as a Python method to implement functions similar to private variables.

In general, a descriptor is an object property with binding behavior, and its attribute access will be overwritten by methods in the descriptor protocol. These methods are _ get _, _ set _, and _ delete __. If any of these methods defines an object, it is considered a descriptor. Use Listing 1 to learn more about these methods.

 

Listing 1. descriptor Method

 

__get__(self, instance, owner)__set__(self, instance, value)__delete__(self, instance)      

Where:

_ Get _ is used to access attributes. It returns the attribute value, or an AttributeError error occurs if the Requested attribute does not exist.

_ Set _ will be called in the attribute allocation operation. NO content is returned.

_ Delete _ controls the delete operation. NO content is returned.

Note that the descriptor is assigned to a class instead of an instance. Modifying this class will overwrite or delete the descriptor itself, rather than trigger its code.

Use of descriptors

Consider email attributes. Before assigning a value to this attribute, you must check the mail format. This descriptor allows you to process an email using a regular expression, then validate the format, and assign it to an attribute.

In many other cases, the Python protocol descriptor controls access to attributes, such as protecting the name attribute.

Create Descriptor

You can create a descriptor in many ways:

  • Create a class and override any descriptor method: __set _, _ get _, and _ delete __. This method is used when a descriptor needs to span multiple different classes and attributes, such as type verification.

  • The attribute type can be used to create descriptors more easily and flexibly.

  • The attribute descriptor combines the attribute type method with the Python descriptor.

The following examples are similar in their operations. The difference lies in the implementation method.

Create a descriptor using class methods

class Descriptor(object):     def __init__(self):        self._name = ''     def __get__(self, instance, owner):        print "Getting: %s" % self._name        return self._name     def __set__(self, instance, name):        print "Setting: %s" % name        self._name = name.title()     def __delete__(self, instance):        print "Deleting: %s" %self._name        del self._name class Person(object):    name = Descriptor()

Use the code and view the output:

>>> user = Person()>>> user.name = 'john smith'Setting: john smith>>> user.nameGetting: John Smith'John Smith'>>> del user.nameDeleting: John Smith

The following methods overwrite the _ set _ (), _ get _ (), and _ delete _ () Methods of the parent class to create a descriptor class:

  • Get will output Getting

  • Delete will output Deleting

  • Set will output Setting

Before the assignment, change the attribute value to the title (the first letter is in upper case, and the other letters are in lower case ). This helps store and output names.

The uppercase conversion can also be moved to the _ get _ () method. _ Value has an initial value and is converted to a title based on the get request.

Create a descriptor using the property type

Although the descriptor defined above is valid and can be used normally, you can also use the attribute type method. By using property (), you can easily create available descriptors for any attribute. The syntax for creating property () is property (fget = None, fset = None, fdel = None, doc = None), where:

  • Fget: Method for retrieving attributes

  • Fset: attribute setting method

  • Fdel: attribute deletion method

  • Doc: docstring

This example is rewritten using properties, as shown in.

Class Person (object): def _ init _ (self): self. _ name = ''def fget (self): print" Getting: % s "% self. _ name return self. _ name def fset (self, value): print "Setting: % s" % value self. _ name = value. title () def fdel (self): print "Deleting: % s" % self. _ name del self. _ name = property (fget, fset, fdel, "I'm the property. ") use this code and view the output: >>> user = Person () >>> user. name = 'John smith 'Setting: john smith >>> user. nameGetting: John Smith 'John Smith '> del user. nameDeleting: John Smith

 

Obviously, the results are the same. Note that the fget, fset, and fdel methods are optional. However, if these methods are not specified, an AttributeError error occurs during each operation. For example, when the name attribute is declared, fset is set to None, and then developers try to assign a value to the name attribute. An AttributeError error occurs.

This method can be used to define read-only attributes in the system:

 

Name = property (fget, None, fdel, "I'm the property") user. name = 'John smith 'output: Traceback (most recent call last): File stdin, line 21, in m has duleuser. name = 'John smith 'AttributeError: can't set attribute

Use attribute modifiers to create Descriptors

You can use the Python modifier to create a descriptor, as shown in. Python modifiers are specific modifications to the Python syntax, allowing you to easily change functions and methods. In this example, the attribute management method is modified. Find more information about the Python modifier in the developerWorks Article Decorators make magic easy.

class Person(object):     def __init__(self):        self._name = ''     @property    def name(self):        print "Getting: %s" % self._name        return self._name     @name.setter    def name(self, value):        print "Setting: %s" % value        self._name = value.title()     @name.deleter    def name(self):        print ">Deleting: %s" % self._name        del self._name

  

Create a descriptor at runtime

The name attribute is used in all previous examples. This method has the following limitations: _ set _ (), _ get _ (), and _ delete _ () must be overwritten for each attribute __(). Listing 5 provides a possible solution to help developers add property properties at runtime. This solution uses the attribute type to construct the data descriptor.

Use attribute modifiers to create Descriptors

  

Class Person (object): def addProperty (self, attribute): # create local setter and getter with a special attribute name getter = lambda self: self. _ getProperty (attribute) setter = lambda self, value: self. _ setProperty (attribute, value) # construct property attribute and add it to the class setattr (self. _ class __, attribute, property (fget = getter, \ fset = setter, \ doc = "Auto-generated method") def _ setProperty (self, attribute, value ): print "Setting: % s = % s" % (attribute, value) setattr (self, '_' + attribute, value. title () def _ getProperty (self, attribute): print "Getting: % s" % attribute return getattr (self, '_' + attribute) let's run this code: >>> user = Person () >>> user. addProperty ('name') >>> user. addProperty ('phone') >>> user. name = 'John smith 'Setting: name = john smith >>> user. phone = '000000' Setting: phone = 12345 >>> user. nameGetting: name 'John Smith '>>> user. _ dict __{ '_ phone': '000000',' _ name': 'John Smith '}

 

This will create the name and phone attributes at runtime. They can be accessed according to the corresponding name, but according to the definition in the _ setProperty method, they will be stored in the object namespace directory as _ name and _ phone. Basically, name and phone are internal _ name and _ phone access characters.

When developers try to add the name property, you may have questions about the _ name property in the system. In fact, it overwrites the existing _ name attribute with the new property. The Code allows you to control how attributes are processed within a class.

 

  

 

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.