Newbie Question - Overloading ==

X

xkenneth

So i generally write quite a few classes, and in most I need to
overload the == operator.

If i have two classes, like below:

Class A:
attribute a
attribute b

Class B:
attribute a
attribute c

So if I've overloaded their respective __eq__ functions, and I want to
test whether or not the individual classes attributes are equal, the
code might look something like this:

class A:
def __eq__(self,other):
return self.a == other.a and self.b == other.b

class B:
def __eq__(self,other):
return self.a == other.a and self.c == other.c

Now obviously, if I test an instance of either class equal to each
other, an attribute error will be thrown, how do I handle this? I
could rewrite every __eq__ function and catch attribute errors, but
that's tedious, and seemingly unpythonic. Also, I don't want an
attribute error thrown whenever two classes are compared that don't
have the same attributes.

I have a sneaky feeling I'm doing something completely unpythonic
here.

Thanks!

Regards,
Kenneth Miller
 
A

Amit Gupta

class A:
def __eq__(self,other):
return self.a == other.a and self.b == other.b

class B:
def __eq__(self,other):
return self.a == other.a and self.c == other.c
Thanks!

Regards,
Kenneth Miller

Can't say aboyt unpythonic: I am no expert at that: but to avoid
catching Attribute-Error everywhere, you can redefine __eq__ as
def __eq__(self, other) :
try :
return <>
except AttributeError:
return False
 
X

xkenneth

Yeah, this is what I'm talking about:
def __eq__(self, other) :
  try :
     return <>
  except AttributeError:
     return False

That seems a bit nasty to me.
 
C

Carl Banks

So i generally write quite a few classes, and in most I need to
overload the == operator.

If i have two classes, like below:

Class A:
attribute a
attribute b

Class B:
attribute a
attribute c

So if I've overloaded their respective __eq__ functions, and I want to
test whether or not the individual classes attributes are equal, the
code might look something like this:

class A:
def __eq__(self,other):
return self.a == other.a and self.b == other.b

class B:
def __eq__(self,other):
return self.a == other.a and self.c == other.c

Now obviously, if I test an instance of either class equal to each
other, an attribute error will be thrown, how do I handle this? I
could rewrite every __eq__ function and catch attribute errors, but
that's tedious, and seemingly unpythonic. Also, I don't want an
attribute error thrown whenever two classes are compared that don't
have the same attributes.

What do you want to happen?

What I'd suggest, without knowing more about your problem, is to
define a method to return some kind of signature to compare instead.
For instance, you could create a dict of the attributes you care
about, and return that. The comparison


class A(object):
def comparison_signature(self):
return { 'a': self.a, 'b': self.b }
def __eq__(self,other):
return self.comparison_signature() ==
other.comparison_signature()

class B(object):
def comparison_signature(self):
return { 'a': self.a, 'c': self.c }
def __eq__(self,other):
return self.comparison_signature() ==
other.comparison_signature()


This I suspect would handle your problem gracefully, assuming that
objects of different types should be considered not equal and have a
different set of attributes in the signature.

For extra credit, you can factor the __eq__ method into a parent class
and inherit the comparison in A and B.


Carl Banks
 
B

bruno.desthuilliers

Surely an A isn't equal to every other object which just happens to have
the same attributes 'a' and 'b'?

And why not ?-)
I would have thoughts the tests want to be
something like:

class A:
def __eq__(self,other):
return (isinstance(other, A) and
self.a == other.a and self.b == other.b)

(and similar for B) with either an isinstance or exact match required for
the type.

I don't think there's a clear rule here. Python is dynamically typed
for good reasons, and MHO is that you should not fight against this
unless you have equally good reasons to do so.
 
A

Amit Gupta

Yeah, this is what I'm talking about:


That seems a bit nasty to me.

One thing about python (IMO); you can't just say this doesn't look
good. You need to say: why do you think this is not good.
To me, it appears a concise and local solution to your problem.
 
X

xkenneth

One thing about python (IMO); you can't just say this doesn't look
good. You need to say: why do you think this is not good.
To me, it appears a concise and local solution to your problem.

Yes it is, but it's also tedious and lengthy for should-be simple
statements.
 
B

Bruno Desthuilliers

Duncan Booth a écrit :
I fully agree with that, but an apple != a pear, even if they are the same
size and colour.

It mostly depends on the problem at hand. It may be that for some
problem, an apple == a pear if they have the same size and colour.
There will be some types where you can have equality
between objects of different types (e.g. int/float), but more often the
fact that they are different types wil automatically mean they are not
equal.

'most often' != 'always' !-)
 
L

Lie

I fully agree with that, but an apple != a pear, even if they are the same
size and colour. There will be some types where you can have equality
between objects of different types (e.g. int/float), but more often the
fact that they are different types wil automatically mean they are not
equal.

Even though an apple != a pear, sometimes when we just don't need to
care between their differences we can treat them as equal, that's what
duck typing is. It really depends on your need if you decided to use
or not to use isinstance checking, in most cases you'd want them to be
checked, but sometimes you just want to know whether the two objects
has the same values on their relevant attributes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top