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