brain storm brain storm - 1 year ago 77
Python Question

maximum recursion depth while using __setattr__ in python new style object?

I have the following code which comprises of a person class and a Manager class that delegates to a person class. I am using

new style object
(derived from
) and running python 2.7.
I geth maximum recursion depth which I am unable to understand. I know the problem happens when setattr is used (when I commented this out in manager class, I see it works fine).
why this recursion occurs and how to avoid it.

class Person(object):
def __init__(self,name,job=None, pay=0):

def lastName(self):

def giveraise(self,percent):*(1+percent))

def __str__(self):
return '[Person: %s, %s]' %(,

class Manager(object):
def __init__(self,name,pay):

def giveraise(self, percent, bonus=0.10):

def __getattr__(self,attr):
print "calling getattr"
return getattr(self.person, attr)

def __setattr__(self,attr, value):
print "calling setattr"

def __str__(self):
return str(self.person)

if __name__=="__main__":

sue = Person("sue Jones","dev",10000)
print sue
print sue.lastName()

print "- -"*25

tom = Manager("Tom mandy", 50000)
print tom
print tom.lastName()

Answer Source

The problem is that in Manager.__init__, you call __setattr__ to set the attribute person. But in __setattr__, you assume that self.person has already been set and has a well defined __dict__. In reality, it hasn't been set yet, so you end up calling __getattr__ which calls itself forever trying to get self.person.

One possible fix here is to bypass the initial call to __setattr__ in Manager.__init__:

class Manager(object):
    def __init__(self,name,pay):

This should avoid the call to "__getattr__('person')" since self.person will already be set and normal attribute lookup will work1.

1__getattr__ is only called if normal attribute lookup fails

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download