为什么这些魔术方法不是递归的?
Why aren't these magic methods recursive?
这里有一个 Python class 实现了一些 magic methods:
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)
的调用,这是对...的调用。好吧,你明白了。
不会导致方法中使用的>
调用自己的方法。为什么?
您没有在 self
上调用 >
。您在 self.value
上调用它,这是一个整数值(例如,完全不同的类型)。
如果您使用过:
def __gt__(self, other):
return self > other
你也会陷入死循环。
这里有一个 Python class 实现了一些 magic methods:
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)
的调用,这是对...的调用。好吧,你明白了。
不会导致方法中使用的>
调用自己的方法。为什么?
您没有在 self
上调用 >
。您在 self.value
上调用它,这是一个整数值(例如,完全不同的类型)。
如果您使用过:
def __gt__(self, other):
return self > other
你也会陷入死循环。