Compare the use of __getattr__ and __getattribute__ in Python to get properties

Source: Internet
Author: User
It is believed that most of the time we do not need to pay attention to the details of GetAttribute and getattr (at least myself:)),
In general, when consuming our custom classes, we understand the structure of the class and do not deliberately deviate from it, causing some property access errors.

However, as a curious and pursuit of the temperament of the Python baby, how may not be a little bit of research. Well, in fact, it is on GitHub read an open source project Sinaweibopy Source to see, the code is very interesting, just as a practical example, to see how to customize the implementation of GETTATTR to make the code more dynamic elegance:

# Examples are simplified on the original basis, excluding dependencies and disturbances, see the original Project Class Urlgenerator (object):  def __init__ (self, root_url):    Self.url = root_ URL  def __getattr__ (self, item):    If Item = = ' Get ' or item = = ' Post ':      print Self.url    return Urlgenerator (' {}/{} '. Format (Self.url, item) Url_gen = Urlgenerator (' http://xxxx ') url_gen.users.show.get>>> http://xxxx/ Users/show

Make full use of getattr will be called when the corresponding instance property is not found, convenient to generate the corresponding URL through the chain call, the source code in the encounter HTTP method when the return of a
The callable object is more elegant, and the chained operation is not only elegant but also good at explaining the meaning of the invoked interface (the RESTful interface).

Example
1.__getattr__ Example:

Class Test (object):  def __init__ (self,name):    self.name = name  def __getattr__ (self, value):    if value = = ' address ':      return ' China ' if __name__== ' __main__ ':  test = Test (' Letian ')  print test.name  print test.address  test.address = ' Anhui '  print test.address

Operation Result:

Letianchinaanhui

If you call a method that is not defined in a class, __getattr__ also returns a method, for example:

Class Test (object):  def __init__ (self,name):    self.name = name  def __getattr__ (self, value):    return lenif __name__== "__main__":  test = Test (' Letian ')  print test.getlength (' Letian ')

Operation Result:
6

2.__getattribute__ Example:

Class Test (object):  def __init__ (self,name):    self.name = name  def __getattribute__ (self, value):    if Value = = ' Address ':      return ' China '    if __name__== ' __main__ ':  test = Test (' Letian ')  print Test.name  print test.address  test.address = ' Anhui '  print test.address

Operation Result:

Nonechinachina

Deep thinking
Since it is possible to implement some elegant functions by customizing the GetAttr custom method of the class, naturally we have to have some understanding of it, including the custom method that is similar to it getattribute

1. Acquisition and interception as instance attributes
When an instance property is accessed, getattribute is called unconditionally, and if it does not implement its own GetAttr method, it throws a attributeerror hint that the property cannot be found, and if it customizes its own GetAttr method, The method is called when the attribute is not found, such as in the example above. So it is a good idea to implement some functionality by implementing a custom GetAttr method without the attribute being found, as it does not have to be called every time the GetAttribute method invokes a property access that might affect some normal conditions:

Class Test (object):  def __init__ (self, p):    SELF.P = P  def __getattr__ (self, item):    return ' default ' t = Test (' p1 ') print t.pprint t.p2>>> p1>>> default

2. Prevent infinite recursion when customizing getattribute
Because GetAttribute is always called when the property is accessed, the custom GetAttribute method also needs to return the corresponding property, and the self.__dict__ value will continue to be lowered with getattribute, resulting in a cyclic call:

Class Aboutattr (object):  def __init__ (self, name):    self.name = name  def __getattribute__ (self, item):    try:      return Super (aboutattr, self). __GETATTRIBUTE__ (item)    except Keyerror:      return ' default '

This is done by invoking the binding Super object to get the property of formation, which is actually the same as object.__getattribute__ (self, item) for the modern class:

By default, custom classes inherit the GetAttribute method from object and are fully available for property lookups
The implementation of GetAttribute is still very abstract, just need to bind the corresponding instance object and the name of the property to be found.
3. At the same time covering the getattribute and getattr, in getattribute need to imitate the original behavior to throw Attributeerror or manually call GetAttr

Class Aboutattr (object):  def __init__ (self, name):    self.name = name  def __getattribute__ (self, item):    try:      return Super (aboutattr, self). __GETATTRIBUTE__ (item)    except Keyerror:      return ' default '    Except Attributeerror as ex:      print ex  def __getattr__ (self, item):    return ' default ' at = aboutattr (' Test ') Print At.nameprint at.not_exised>>>test>>> ' aboutattr ' object has no attribute ' not_exised ' >> >none

The GetAttr method in the above example is not called at all, because the original attributeerror is handled by us without throwing or manually calling GetAttr, so the result of accessing not_existed is none and not default.

  • 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.