I have another question for you.
I have a python class with a list 'metainfo'. This list contains variable names that my class might contain. I wrote a __eq__
method that returns True if the both self
and other
have the same variables from metainfo
and those variables have the same value.
Here is my implementation:
def __eq__(self, other):
for attr in self.metainfo:
try:
ours = getattr(self, attr)
try:
theirs = getattr(other, attr)
if ours != theirs:
return False
except AttributeError:
return False
except AttributeError:
try:
theirs = getattr(other, attr)
return False
except AttributeError:
pass
return True
Does anyone have any suggestions as to how I can make this code easier on the eye? Be as ruthless as you please.
Use getattr
's third argument to set distinct default values:
def __eq__(self, other):
return all(getattr(self, a, Ellipsis) == getattr(other, a, Ellipsis)
for a in self.metainfo)
As the default value, set something that will never be an actual value, such as Ellipsis
†. Thus the values will match only if both objects contain the same value for a certain attribute or if both do not have said attribute.
Edit: as Nadia points out, NotImplemented
may be a more appropriate constant (unless you're storing the result of rich comparisons...).
Edit 2: Indeed, as Lac points out, just using hasattr
results in a more readable solution:
def __eq__(self, other):
return all(hasattr(self, a) == hasattr(other, a) and
getattr(self, a) == getattr(other, a) for a in self.metainfo)
†: for extra obscurity you could write ...
instead of Ellipsis
, thus getattr(self, a, ...)
etc. No, don't do it :)
I would add a docstring which explains what it compares, as you did in your question.
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