I want to know that if I have class like this:
class TestClass(object):
def __init__(self):
self.a = 20
self.b = 30
obj = TestClass()
When I write obj.a, which of the following is called first?
TestClass.__getattribute__("a")TestClass.__getattr__("a")getattr(obj, "a")obj.__dict__['a']
I have a similar question for setattr
According to Python 2.7 docs:
object._getattr_(self, name)
Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception.
It says "not found […] in usual places". What are the "usual places". I want to know when __getattr__ is called.
Also, what is the difference between __getattr__ and __getattribute__?
Can anyone give me example where all of these are used?
It’s a bit complicated. Here’s the sequence of checks Python does if you request an attribute of an object.
First, Python will check if the object’s class has a
__getattribute__method. If it doesn’t have one defined, it will inheritobject.__getattribute__which implements the other ways of finding the attribute’s values.The next check is in the object’s class’s
__dict__. However, even if a value is found there, it may not be the result of the attribute lookup! Only "data descriptors" will take precedence if found here. The most common data descriptor is apropertyobject, which is a wrapper around a function that will be called each time an attribute is accessed. You can create a property with a decorator:In this class,
myAttris a data descriptor. That simply means that it implements the descriptor protocol by having both__get__and__set__methods. Apropertyis a data descriptor.If the class doesn’t have anything in its
__dict__with the requested name,object.__getattribute__searches through its base classes (following the MRO) to see if one is inherited. An inherited data descriptor works just like one in the object’s class.If a data descriptor was found, its
__get__method is called and the return value becomes the value of the attribute lookup. If an object that is not a data descriptor was found, it is held on to for a moment, but not returned just yet.Next, the object’s own
__dict__is checked for the attribute. This is where most normal member variables are found.If the object’s
__dict__didn’t have anything, but the earlier search through the class (or base classes) found something other than a data descriptor, it takes next precedence. An ordinary class variable will be simply returned, but "non-data descriptors" will get a little more processing.A non-data descriptor is an object with a
__get__method, but no__set__method. The most common kinds of non-data descriptors are functions, which become bound methods when accessed as a non-data descriptor from an object (this is how Python can pass the object as the first argument automatically). The descriptor’s__get__method will be called and it’s return value will be the result of the attribute lookup.Finally, if none of the previous checks succeeded,
__getattr__will be called, if it exists.Here are some classes that use steadily increasing priority attribute access mechanisms to override the behavior of their parent class:
And, a demonstration of the classes in action:
O1 (
__getattr__):O2 (class variables and non-data descriptors):
O3 (instance variables, including a locally overridden method):
O4 (data descriptors, using the
propertydecorator):O5 (
__getattribute__):