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

Reply via email to