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 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.
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:
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 returnNotImplemented
, 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
as there is no such thing as __req__
in Python's data model.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With