Reputation: 2709
I have the following code:
#-*-coding:utf-8-*-
class A(object):
def __init__(self, x):
self.x = x
def __getattr__(self, name): # `__getattr__` will be called undefined attribute
print "get: ", name
return self.__dict__.get(name)
def __setattr__(self, name, value):
print "set:", name, value
self.__dict__[name] = value
def __getattribute__(self, name): # `__getattribute__` will be called all attributes
print "attribute:", name
return object.__getattribute__(self, name)
if __name__ == "__main__":
a = A(10)
print '---------------'
a.x
print '---------------'
a.y = 20
print '---------------'
a.z
And the result is :
set: x 10
attribute: __dict__
---------------
attribute: x
---------------
set: y 20
attribute: __dict__
---------------
attribute: z
get: z
attribute: __dict__
When I called a=A(10)
, why __getattribute__
is called ? This is my thought: there is self.x = x
in __init__
, and __setattr__
catch __init__
, self.__dict__[name] = value
catch __getattrbute__
. So, __getattribute__
is called. Does my thought right ? What's wrong ?
Upvotes: 2
Views: 976
Reputation: 280181
The arrow is pointing to where __setattr__
invokes __getattribute__
:
def __setattr__(self, name, value):
print "set:", name, value
self.__dict__[name] = value
# ^ attribute access!
__getattribute__
handles all explicit attribute lookup, including __dict__
. I believe this is the conclusion you already came to; I couldn't quite understand what you were trying to say.
Upvotes: 3