'Reversed' Python 中的比较运算符

'Reversed' comparison operator in Python

class Inner():

    def __init__(self, x):
        self.x = x

    def __eq__(self, other):
        if isinstance(other, Inner):
            return self.x == other.x
        else:
            raise TypeError("Incorrect type to compare")

class Outer():

    def __init__(self, y):
        self.y = Inner(y)

    def __eq__(self, other):
        if isinstance(other, Outer):
            return self.y == other.y
        elif isinstance(other, Inner):
            return self.y == other
        else:
            raise TypeError("Incorrect type to compare")


if __name__ == "__main__":

    a = Outer(1)
    b = Inner(1)

    print(a == b) # ok no problem
    print(b == a) # This will raise a type error

在示例中我有内部和外部 class。我无法控制 Inner 的实现,只是想模拟这种情况。我只能控制 Outer 的行为。我希望外部实例能够与内部实例进行比较(不仅仅是相等)。对于给定的实现,只有第一次比较有效,因为调用 Outer 的 __eq__ 方法允许与 Outer 和 Inner 实例进行比较,但第二次调用 Inner 的 __eq__ 方法不允许与 Outer 进行比较 -哎呀,它不知道 Outer 存在,为什么要费心去实现它。 有没有办法让第二种类型的比较起作用,类似于 __radd__ 之类的功能。 我知道,例如在 C++ 中,您可以使用内联运算符定义来解决这个问题,但我们在 Python.

中没有这样的定义

不要把它说得太细:Inner.__eq__ 坏了。至少,它应该 return NotImplemented 而不是抛出错误,这将允许 Python 尝试反向比较:

When NotImplemented is returned, the interpreter will then try the reflected operation on the other type, or some other fallback, depending on the operator. If all attempted operations return NotImplemented, the interpreter will raise an appropriate exception.

更好的是它会使用 "duck typing",而不是坚持特定的 class(除非 class,而不是它的界面,是比较中明确重要的部分) :

def __eq__(self, other):
    try:
        return self.x == other.x
    except AttributeError:
        return NotImplemented

但是,正如您所说您无法控制它,您将不得不手动实现类似的功能,例如:

def compare(a, b):
    """'Safe' comparison between two objects."""
    try:
        return a == b
    except TypeError:
        return b == a

因为 Python's data model 中没有 __req__ 这样的东西。