Python中的“反向”比较运算符 [英] 'Reversed' comparison operator in Python

查看:57
本文介绍了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

在该示例中,我具有内部和外部类。我无法控制Inner只是想模拟这种情况的工具。我只能控制外层的行为。我希望外部实例能够与内部实例进行比较(不仅仅是相等)。在给定的实现中,只有第一个比较有效,因为调用Outer的 __ eq __ 方法可以与Outer和Inner实例进行比较,但是第二个调用是Inner的 __ eq __ 不允许与Outer进行比较-哎呀,它不知道Outer存在,为什么要麻烦实现它。
是否有一种方法可以使第二种比较工作,例如 __ radd __ 之类的功能。例如,我知道
是在C ++中使用内联运算符定义解决的,但在Python中却没有。

In the example I have inner and outer class. I have no control over what Inner implements just wanted to simulate the situation. I have only control over Outer's behavior. I want Outer instances to be able to compare to Inner instances (not just equality). With the given implementation only the first comparison works because that is calling Outer's __eq__ method allowed to be compared to Outer and Inner instances but the second one is calling Inner's __eq__ which will not allow the comparison to Outer - heck it doesn't know Outer exists why should it bother to implement it. Is there a way to get the second type of comparison to work, with something similar like the __radd__ and such functions. I know for instance in C++ you resolve this with inline operator definitions, but we don't have such in Python.

推荐答案

不要说得太清楚: Inner .__ eq __ 已损坏。至少,而不是抛出错误,它应该 return NotImplemented ,这将允许Python尝试进行反向比较:

Not to put too fine a point on it: Inner.__eq__ is broken. At the very least, rather than throwing an error it should return NotImplemented, which would allow Python to try the reverse comparison:


NotImplemented 返回,然后解释器将尝试对另一种类型的
反映操作或其他后备方式,取决于操作符
。如果所有尝试的操作均返回
NotImplemented ,则解释器将引发适当的异常。

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.

更好的方法是使用 鸭子输入 ,而不是坚持使用特定的类(除非类,而不是其接口是比较的显着重要部分):

Better yet it would use "duck typing", rather than insisting on a specific class (unless the class, rather than its interface, is an explicitly important part of the comparison):

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






但是,正如您所说的那样,您将必须手动实现类似的功能,例如:


However, as you say you cannot control this, you will have to manually implement similar functionality, for example:

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

因为在__req __ 这样的东西nofollow> Python的数据模型

as there is no such thing as __req__ in Python's data model.

这篇关于Python中的“反向”比较运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆