2016-07-18 37 views
5
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的行为。我希望外部实例能够与内部实例(不仅仅是相等)进行比较。与给定的实现只有第一次比较工作,因为这是调用Outer的__eq__方法允许与外部和内部实例进行比较,但第二个调用内部的__eq__这将不允许与外部的比较 - 它不知道外部存在为什么要这么麻烦呢? 有没有办法让第二种比较工作,类似__radd__等功能。 我知道例如在C++中用内联运算符定义解决这个问题,但我们在Python中没有这样的解决方案。Python中的'反转'比较运算符

回答

2

不要把它放得太细:Inner.__eq__坏了。最起码,而不是抛出一个错误它应该return NotImplemented,这样可以让Python来尝试反向比较:

当返回NotImplemented,解释器将尝试在 反映在其他类型的操作,或一些其他的后备, 取决于运营商。如果所有尝试的操作都返回 NotImplemented,则解释器将引发适当的异常。

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

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__这样的东西。