为什么这些魔术方法不是递归的?

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

你也会陷入死循环。