cat*_*cat 0 python recursion operator-overloading python-3.x
这是一个实现一些魔术方法的 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)
Run Code Online (Sandbox Code Playgroud)
它实现了在某些对象上定义的(尽管是冗余的)方法,并允许比较和(在这种__setattr__情况下)赋值挂钩:
>>> a.inc()
value changed its value from 0 to 1
1
Run Code Online (Sandbox Code Playgroud)
假设我们重新定义__setattr__以使其更简单:
def __setattr__(self, name, value):
self.__setattr__(name, value)
Run Code Online (Sandbox Code Playgroud)
现在尝试分配给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
Run Code Online (Sandbox Code Playgroud)
嗯,这是预料之中的。该函数__setattr__是递归的;这就是为什么我们需要使用super().
我的问题是,为什么这种递归性不适用于其他魔术方法?也就是说,当我调用 时obj.__gt__(otherval),它与说obj > otherval,哪个是对 的调用obj.__gt__(otherval),哪个是对……的调用相同,您明白了。
它不会导致方法中>使用的方法调用自己的方法。为什么?
你是不是调用>上self。您在 上调用它self.value,这是一个整数值(例如完全不同的类型)。
如果您使用:
def __gt__(self, other):
return self > other
Run Code Online (Sandbox Code Playgroud)
你也会陷入无限循环。