python--Management Properties (2)

Source: Internet
Author: User

__getattr__ and __getattribute__
The attribute property and descriptor are now described to manage specific properties "reference here", while the __getattr__ and __getattribute__ operator overloading methods provide another way to intercept the properties of class instances, which are more widely used, But their performance is different:

"1" __getattr__ for undefined attributeRun-that is, the property is not stored on the instance or is not inherited from one of its classes.
"2" __getattribute__ for each property, therefore, when using it, care must be taken to avoid recursive loops by passing property access to the superclass.

These two methods are representatives of a set of property interception methods, which also include __setattr__ and __delattr__, as well.

Unlike attributes and descriptors, these methods are part of the Python "operator overloading" protocol-a special named method of a class that inherits from a subclass. The __getattr__ and __getattribute__ methods are also more common than attributes and descriptors, and are used to intercept almost all instances of property acquisition, not just specific names. Therefore, these two methods are suitable for general delegate-based encoding.

--------------------------------------------------------------------------------------------------------------- -------------------------

Basic knowledge
If a class defines or inherits the following methods, they will automatically run when one instance is used for the case mentioned in the following comments:

In all of these, self is typically the principal instance object, name is the string name of the property that will be accessed, and value is the object that will be assigned to the property. Two get methods typically return the value of one property, and the other two methods return none. For example, to capture the acquisition of each property, we can use the above two methods, to capture the property assignment, you can use a third method:

>>> class Catcher:def __getattr__ (self,name):p rint (' Get: ', name) def __setattr__ (Self,name,value):p rint (' Set: ', name,value) >>> X = Catcher () >>> x.jobget:job>>> x.payget:pay>>> X.pay = 99set:pay 99
----------------------------------------------------------------------------------------------------------- -----------------------------

Avoid loops in the attribute interception method

Use these methods to avoid potential recursive loops.
For example, another property fetch inside a __getattribute__ method code will trigger __getattribute__ again, and the code will loop knowing that memory is exhausted:

def __getattribute__ (self,name): x = Self.other
To solve this problem, take a pointer to a higher superclass instead of skipping this level of version--object class is always a superclass, and it works well here:
def __getattribute__ (self,name): x = object.__getattribute__ (self, ' other ')
For __setattr__, the situation is similar and assigning any property within this method will trigger __setattr__ again and create a similar loop:
def __setattr__ (self,name,value): Self.other = value
To solve this problem, assign a property as a key in the __dict__ namespace Dictionary of the instance, thus avoiding the direct property assignment:
def __setattr__ (self,name,value): self.__dict__[' other '] = value
There is also a less common method, __setattr__ can also pass their own property assignment to a higher superclass and avoid loops, just like __getattribute__:
def __setattr__ (Self,name,value): object.__setattr__ (self, ' other ', value)
Instead, we cannot use the __dict__ technique to avoid loops in __getattribute__:
def __getattribute__ (self,name): x = self.__dict__[' other ']
Because getting the __dict__ property will trigger __getattribute__ again, resulting in a recursive loop.
----------------------------------------------------------------------------------------------------------- -----------------------------

Example
Here is the same example as the attribute and descriptor, but is implemented using the property operator overloading method.

Class Person:    def __init__ (self,name):        self._name  = name    def __getattr__ (self,attr):        if attr = = ' Name ':            print (' Fetch ... ')            return self._name        else:            raise Attributeerror (attr)    def __setattr__ ( Self,attr,value):        if attr = = ' name ':            print (' Change ... ')            attr = ' _name '        self.__dict__[attr] = Value    def __delattr__ (self,attr):        if attr = = ' name ':            print (' Remove ... ')            attr = ' _name '        del Self.__dict__[attr]bob = Person (' Bob Smith ') print (bob.name) Bob.name = ' Robert Smith ' Print (Bob.name) del Bob.nameprint ( '-' *20 ' Sue = person (' Sue Jones ') print (sue.name) #print (person.name.__doc__) #这里没有与特性等同的用法
Note that the property assignment in the __init__ constructor also triggers __setattr__, which captures each property assignment, even those within the class itself. Running this code will produce the same output:
Fetch ... Bob Smithchange...fetch ... Robert smithremove ...--------------------fetch ... Sue Jones
Also note that unlike attributes and descriptors, there is no direct declaration of the specified document for a property.

To implement the same result as __getattribute__, replace the __getattr__ in the example with the following code, because it captures all of the property fetches, you must avoid looping by passing the new fetch to the superclass:
def __getattribute__ (self,attr): if attr = = ' name ':p rint (' Fetch ... ') attr = ' _name ' return object.__getattribute__ (self, attr
These examples, while consistent with the code written by the attributes and descriptors, do not emphasize the usefulness of these tools. Because they are generic, __getattr__ and __getattribute__ are more commonly used in delegate-based code. It is better to use attributes and descriptors in cases where only a single attribute is customary.

python--Management Properties (2)

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.