Inverted 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 

In the example, I have an inner and outer class. I have no control over the fact that Internal Instruments simply wanted to mimic the situation. I control only external behavior. I want external instances to be able to compare with internal instances (and not just equality). Only the first comparison is performed with this implementation, because the call to the Outer __eq__ method is allowed for comparison with external and internal instances, and the second calls Inner __eq__ , which does not allow comparison with Outer - heck it doesn 'I know that Outer exists, why it should to implement it. Is there a way to get the second type of comparison to work, with something similar to __radd__ and such functions. I know, for example, in C ++ you enable this using the built-in operator definitions, but we don’t have them in Python.

+5
source share
1 answer

Do not put too thin a dot: Inner.__eq__ broken. At least, instead of throwing an error, it should return NotImplemented , which would allow Python to try the reverse comparison:

When NotImplemented returns, the interpreter will try to perform the reflected operation on another type or some other backup, depending on the operator. If all attempted operations are returned NotImplemented , the interpreter will raise a corresponding exception.

It is better to use duck typing instead of insisting on a specific class (if only the class, and not its interface, is clearly an 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 functions, for example:

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

since __req__ does not exist in the Python data model .

+2
source

All Articles