这是一个实现一些magic methods的Python类:
class A():
def __init__(self, value):
self.value = value
def inc(self):
self.value += 1
return self.value
def dec(self):
self.value -= 1
return self.value
def __eq__(self, other):
return self.value == other
def __gt__(self, other):
return self.value > other
def __lt__(self, other):
return self.value < other
def __setattr__(self, name, value):
try:
self.value
except:
pass
else:
print(name, "changed its value from", self.value, "to", value)
finally:
super().__setattr__(name, value)
它实现了某些对象上定义的(虽然是冗余的)方法,并且允许比较和(在__setattr__
情况下)赋值挂钩:
>>> a.inc()
value changed its value from 0 to 1
1
假设我们重新定义__setattr__
以使其更简单:
def __setattr__(self, name, value):
self.__setattr__(name, value)
现在尝试分配到self.value
会让你一记耳光:
File "<pyshell#50>", line 17, in __setattr__
self.__setattr__(name, value)
File "<pyshell#50>", line 17, in __setattr__
self.__setattr__(name, value)
File "<pyshell#50>", line 17, in __setattr__
self.__setattr__(name, value)
File "<pyshell#50>", line 17, in __setattr__
self.__setattr__(name, value)
File "<pyshell#50>", line 17, in __setattr__
self.__setattr__(name, value)
RecursionError: maximum recursion depth exceeded
嗯,这是预期的。函数__setattr__
是递归的;这就是为什么我们需要使用super()
。
我的问题是,为什么这种递归不适用于其他魔术方法;也就是说,当我拨打obj.__gt__(otherval)
时,它就像说obj > otherval
一样,这是对obj.__gt__(otherval)
的调用,这是对...的调用...好吧,你得到它。
它不会导致方法中使用的>
调用自己的方法。为什么呢?
答案 0 :(得分:4)
您未在>
上调用self
。您在self.value
上调用它,这是一个整数值(例如完全不同的类型)。
如果您使用:
def __gt__(self, other):
return self > other
你也会陷入无休止的循环中。