
class A(object): def __init__(self, obj): self.__obj = obj def __str__(self): return str(self.__obj) __repr__ = __str__ def __getattribute__(self, attr): return getattr(self.__obj, attr) A().append(1) #RuntimeError: maximum recursion depth exceeded while calling a Python object
已知:
不解:
1 sudo987 OP 发完贴就明白了,__getattribute__里调用 getattr 会重新调用外层方法的__getattribute__, 从而造成死循环。 |
2 strahe 2016-07-05 23:15:08 +08:00 我今天下午刚碰到这个问题.... |
3 sudo987OP 2016-07-05 23:17:30 +08:00 @strahe 刚才以为明白了,其实还是之前的问题,不懂为什么会出现死循环,我又发了个帖子, http://v2ex.com/t/290524#reply0 |
5 strahe 2016-07-05 23:24:43 +08:00 你不是都说出来了吗?每次引用方法或者属性(除特殊方法外)都会调用"__getattribute__",你调用 self.__obj,本身就是在引用它的一个属性 |
6 shyling 2016-07-05 23:26:13 +08:00 via Android self.__obj |
7 sudo987 OP @strahe 但是 getattr(self.__obj.attr)相当于 self.__obj.attr ,是调用 self.__obj 自身的__getattribute__,和 class A 的__getattribute__不是一个东西,所以我觉得不应该出现死循环。 |
8 sudo987 OP @strahe 啊。。。明白了,问题不在 self.__obj.attr 去的 attr 上,而是在 self 取得__obj 上,在这里出现了死循环,谢谢。 |
9 ruanimal 2016-07-06 08:34:48 +08:00 自定义了__getattribute__,所有属性和字典访问都会通过自定义的__getattribute__,会死循环的。。 |
10 nimdanoob 2016-07-06 10:43:23 +08:00 可能 没太仔细看吧,很好理解 |
11 kaneg 2016-07-06 13:45:15 +08:00 根据楼主提供的代码,我觉得你想达到的效果是用 A 来代理 obj ,覆盖__getattr__而不是__getattribute__可以达到此类效果: '''python class A(object): def __init__(self, obj): super(A, self).__init__() self.obj = obj def __getattr__(self, item): if item == 'obj': return self.obj else: return self.obj.__getattribute__(item) ''' |