如何实现__getattribute__而没有无限递归错误? [英] How do I implement __getattribute__ without an infinite recursion error?
问题描述
我想重写对类中一个变量的访问,但通常返回所有其他变量.如何使用__getattribute__
完成此操作?
I want to override access to one variable in a class, but return all others normally. How do I accomplish this with __getattribute__
?
我尝试了以下操作(这也应该说明我正在尝试执行的操作),但是出现了递归错误:
I tried the following (which should also illustrate what I'm trying to do) but I get a recursion error:
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else:
return self.__dict__[name]
>>> print D().test
0.0
>>> print D().test2
...
RuntimeError: maximum recursion depth exceeded in cmp
推荐答案
您会遇到递归错误,因为您尝试访问__getattribute__
内部的self.__dict__
属性会再次调用您的__getattribute__
.如果您改用object
的__getattribute__
,它将起作用:
You get a recursion error because your attempt to access the self.__dict__
attribute inside __getattribute__
invokes your __getattribute__
again. If you use object
's __getattribute__
instead, it works:
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else:
return object.__getattribute__(self, name)
这是有效的,因为object
(在此示例中)是基类.通过调用__getattribute__
的基本版本,您可以避免以前遇到的递归地狱.
This works because object
(in this example) is the base class. By calling the base version of __getattribute__
you avoid the recursive hell you were in before.
Ipython输出,其中包含foo.py中的代码:
Ipython output with code in foo.py:
In [1]: from foo import *
In [2]: d = D()
In [3]: d.test
Out[3]: 0.0
In [4]: d.test2
Out[4]: 21
更新:
标题为当前文档中的对新型类的更多属性访问 ,他们建议完全这样做以避免无限递归.
There's something in the section titled More attribute access for new-style classes in the current documentation, where they recommend doing exactly this to avoid the infinite recursion.
这篇关于如何实现__getattribute__而没有无限递归错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!