On 23/03/13 15:08, Robert Sjoblom wrote:
Hi list. I'll preface this by saying that I am very grateful for all
of you, and thank you in advance to anyone that answers.
I'm currently working on a roulette simulator, because it seemed like
fun. I found out I needed a way to compare two different outcomes, and
it was suggested to me that I should override the __eq__ and __ne__
methods. Said and done, I did:
class Outcome():
def __init__(self, name): #Ignoring odds for now
self.name = name
def __eq__(self, other):
'''returns True if Outcome.name matches other.name''':
if self.name == other.name: return True
def __ne__(self, other):
'''returns True if Outcome.name does not match other.name'''
if self.name != other.name: return True
I'm not sure what relevance a name has for roulette simulator, but okay.
Those two methods are probably better written something like this:
def __eq__(self, other):
return (self.name == other.name)
def __ne__(self, other):
return (self.name != other.name)
Actually, here's an even better way of doing it:
def __eq__(self, other):
if isinstance(other, Outcome):
return (self.name == other.name)
# Give the other object a chance to check for equality.
return NotImplemented
def __ne__(self, other):
return not self == other
Now, this works, as far as this is concerned:
a = Outcome('Bob')
b = Outcome('Ray')
c = Outcome('Bob')
a == b
a == c
True
a != b
True
When testing, you should also test values that give the opposite result. For
example, compare a == b and a != c.
However, if I were to create a class without the __eq__ and __ne__
definitions, what is to prevent me from doing: a.name == b.name ?
Nothing. But consider a more complicated example. Which would you rather write?
a.name.lower() == b.name.lower() and a.age == b.age and a.sex == b.sex
a == b
The idea of defining __eq__ is that you can hide all the complexity of checking
equality in a single method. For example, the __eq__ for dicts might look
something like this:
def __eq__(self, other):
if self is other:
return True
if not isinstance(self, other):
return NotImplemented
if len(self) != len(other):
return False
for key in self:
if key not in other:
return False
if self[key] != self[other]:
return False
return True
Imagine having to write something like that every single time you wanted to
compare to dicts for equality.
Or
am I missing something in my implementation of the overrides? Is there
a reason why I shouldn't do .name comparisons?
As I said, I don't really understand why a roulette outcome has a name in the
first place, but given that it does, I don't any problem with comparing the
names directly. Still, I would probably write it as an __eq__ method, since
it's easier to write a == b than a.name == b.name.
--
Steven
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor