changzhi
changzhi

Reputation: 2709

Python __getattribute__ and __setattr__

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

Answers (1)

user2357112
user2357112

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

Related Questions