Python provides us many possibilities on instance/class attribute, for example:
class A(object):
    def __init__(self):
        self.foo = "hello"
a = A()
There are many ways to access/change the value of self.foo:
a.foo
a.__dict__['foo']
a.__get__ and a.__set__,of course there two are pre-defined methods.a.__getattribute__
__getattr__ and __setattr__
While reading source code, I always get lost of what's their ultimate access order? When I use a.foo, how do I know which method/attribute will get called actually?
Python getattr() The getattr() method returns the value of the named attribute of an object. If not found, it returns the default value provided to the function.
Class attributes are the variables defined directly in the class that are shared by all objects of the class. Instance attributes are attributes or properties attached to an instance of a class. Instance attributes are defined in the constructor. Defined directly inside a class.
__getattr__ 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).
Method 1: To get the list of all the attributes, methods along with some inherited magic methods of a class, we use a built-in called dir() . Method 2: Another way of finding a list of attributes is by using the module inspect .
I found out this great post that has a detailed explanation on object/class attribute lookup.
For object attribute lookup:
Assuming Class is the class and instance is an instance of Class, evaluating instance.foobar roughly equates to this:
Class.__getattribute__ (tp_getattro). The default does this: 
Class.__dict__ have a foobar item that is a data descriptor ? 
Class.__dict__['foobar'].__get__(instance, Class). instance.__dict__ have a 'foobar' item in it?
instance.__dict__['foobar'].Class.__dict__ have a foobar item that is not a data descriptor [9]?
Class.__dict__['foobar'].__get__(instance, klass). [6]Class.__getattr__, call Class.__getattr__('foobar').There is an illustrated image for this:

Please do check out the original blog if interested which gives a outstanding explanation on python class, attribute lookup, and metaclass.
bar = a.foo...
a.__getattribute__('foo')
a.__dict__['foo']
foo's .__get__() if defined on A.The returned value would then be assigned to bar.
a.foo = bar...
a.__getattribute__('foo')
a.__dict__['foo']
foo's .__set__(bar) if defined on A.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With