在python新样式对象中使用_setattr__时的最大递归深度?
我有下面的代码,它由person类和委托给person类的Manager类组成。我正在使用在python新样式对象中使用_setattr__时的最大递归深度?,python,class,object,getattr,setattr,Python,Class,Object,Getattr,Setattr,我有下面的代码,它由person类和委托给person类的Manager类组成。我正在使用新样式对象(源自对象)并运行python 2.7。 我得到了我无法理解的最大递归深度。我知道当使用setattr时会出现问题(当我在manager类中注释掉这一点时,我发现它工作得很好)。 为什么会发生这种递归以及如何避免它 class Person(object): def __init__(self,name,job=None, pay=0): self.name=name
新样式对象
(源自对象
)并运行python 2.7。
我得到了我无法理解的最大递归深度。我知道当使用setattr时会出现问题(当我在manager类中注释掉这一点时,我发现它工作得很好)。
为什么会发生这种递归以及如何避免它
class Person(object):
def __init__(self,name,job=None, pay=0):
self.name=name
self.job=job
self.pay=pay
def lastName(self):
return self.name.split()[-1]
def giveraise(self,percent):
self.pay=int(self.pay*(1+percent))
def __str__(self):
return '[Person: %s, %s]' %(self.name, self.pay)
class Manager(object):
def __init__(self,name,pay):
self.person=Person(name,'mgr',pay)
def giveraise(self, percent, bonus=0.10):
self.person.giveraise(percent+bonus)
def __getattr__(self,attr):
print "calling getattr"
return getattr(self.person, attr)
def __setattr__(self,attr, value):
print "calling setattr"
self.person__dict__["attr"]=value
def __str__(self):
return str(self.person)
if __name__=="__main__":
sue = Person("sue Jones","dev",10000)
sue.giveraise(0.10)
print sue
print sue.lastName()
print "- -"*25
tom = Manager("Tom mandy", 50000)
tom.giveraise(.10)
print tom
print tom.lastName()
问题在于,在
管理器中,您可以调用设置属性人员。但是在\uuuu setattr\uuuuuu
中,您假定已设置了self.person
,并且有一个定义良好的\uuuuuu dict
。事实上,它还没有被设置,所以你最终调用了\uuu getattr\uuuu
,它一直在调用自己,试图获取self.person
这里一个可能的修复方法是绕过对管理器中\uuuuu setattr\uuuuu
的初始调用
class Manager(object):
def __init__(self,name,pay):
self.__dict__['person']=Person(name,'mgr',pay)
def __setattr__(self,attr, value):
print "calling setattr"
self.person__dict__["attr"]=value
这应该避免调用“\uuu getattr\uuuu('person')
”,因为self.person
将已经设置,并且正常的属性查找将工作1
1\uuuuu getattr\uuuuuu
仅在正常属性查找失败时调用mgilson的答案几乎是正确的,但是,在类管理器的\uuuuuu setattr\uuuuuuuu
函数中,在person\uuu dict\uuuuuuu
之间缺少一个点:
class Manager(object):
def __init__(self,name,pay):
self.__dict__['person']=Person(name,'mgr',pay)
def __setattr__(self,attr, value):
print "calling setattr"
self.person__dict__["attr"]=value
当\uuuuu init\uuuuuuu
尝试设置self.person时,\uuuuuu setattr\uuuuuu
查询一个不存在的属性person\uuuuu dict\uuuuuuu
,将调用管理者的\uuuuu getattr\uuuuuu
函数。它反过来查询self.person,而self.person在此阶段不存在,在此阶段您将得到一个\uuuu getattr\uuuu
递归。我将setattr改为:def\uu setattr\uuuuu(self,attr,value):打印“calling setattr”返回setattr(self.person,attr,value)
,但我仍然得到最大递归深度。为什么我得到这个递归深度问题。你的解决方案很好。但我想了解为什么最大递归深度occurs@user1988876--问题是因为在这一点上,self.person
还不存在。(从未设置过)。因此,这会强制调用\uuu getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu,它不应该返回none
或其他什么吗similar@user1988876--因为\uu getattr\uu
中有一行self.person
。如果通过正常方法找不到属性,则调用\uuuu getattr\uuuuu
(再次!)。此处未隐式返回None
。你为什么期望会有这样的结果?