问题
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
:
- direct access
a.foo
- inner dict
a.__dict__['foo']
- get and set
a.__get__
anda.__set__
,of course there two are pre-defined methods. - getattribute
a.__getattribute__
__getattr__
and__setattr__
- maybe more.
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?
回答1:
bar = a.foo
...
- invokes
a.__getattribute__('foo')
- which in turn by default looks up
a.__dict__['foo']
- or invokes
foo
's.__get__()
if defined onA
.
The returned value would then be assigned to bar
.
a.foo = bar
...
- invokes
a.__getattribute__('foo')
- which in turn by default looks up
a.__dict__['foo']
- or invokes
foo
's.__set__(bar)
if defined on A.
回答2:
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:
- Call the type slot for
Class.__getattribute__
(tp_getattro
). The default does this:- Does
Class.__dict__
have afoobar
item that is a data descriptor ?- If yes, return the result of
Class.__dict__['foobar'].__get__(instance, Class)
.
- If yes, return the result of
- Does
instance.__dict__
have a'foobar'
item in it?- If yes, return
instance.__dict__['foobar']
.
- If yes, return
- Does
Class.__dict__
have afoobar
item that is not a data descriptor [9]?- If yes, return the result of
Class.__dict__['foobar'].__get__(instance, klass)
. [6]
- If yes, return the result of
- Does
- If the attribute still wasn't found, and there's a
Class.__getattr__
, callClass.__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.
来源:https://stackoverflow.com/questions/30961069/what-is-the-python-attribute-get-and-set-order