Besides the
False == 0 problem, I encountered another problem that surprised me. Consider the following Python code:
class Foo(object):
def __eq__(self, other):
if isinstance(other, Foo):
return True
return False
f1 = Foo()
f2 = Foo()
f1 == f2 # => True or False ?
f1 != f2 # => True or False ?
What do you expect the result to be in the last two lines?
If you know a little Python, you'll notice that I defined
__eq__ method for class
Foo that consider every
Foo objects as equal. So
f1 == f2 evaluate to
True. But why does
f1 != f2 still evaluate to
True? :(
danran@freecity quoted for me this from
the Python document:
Implementation note: Objects of different types except numbers are ordered by their type names; objects of the same types that don't support proper comparison are ordered by their address.
So when you haven't defined
__ne__ for
Foo and
f1 and
f2 don't have the same address,
f1 != f2 will evaluate to
True.
OK, I know the reason now. But please forgive my ignorance, I didn't know the
__ne__ method until just now. While it is good to have both
__eq__ and
__ne__ to have more
rich behavior, why not be a little smarter when only one of them is defined by the user? For simplicity? Simple to write the application code or simple to implement the language?
I always like the quote from
Bjarne Stroustrup (the father of C++):
Complexity will go somewhere: if not the language then the application code.
I don't know which I'll prefer, because currently my
application code is in fact implementing another language. :p
Update 2008-07-24: gwilym pointed me
this post on comp.lang.python today, which is ranting one of
the Python Zen:
Explicit is better than implicit. It also described the
__eq__/
__ne__ problem and I agree most of the OP's opinion. We can consider Python's KISS to be:
Keep
It
Simple and verbo
Se -- just kidding. :D
Comments (5)
Hrm, after discussing with a friend, I found this is in fact a reasonable behavior. Maybe the reason that I considered this strange is that I'm too much influenced by Ruby. :p
Reading the rationale might also be illuminating:
http://www.python.org/dev/peps/pep-0207/
"The == and != operators are not assumed to be each other's complement (e.g. IEEE 754 floating point numbers do not satisfy this). It is up to the type to implement this if desired. Similar for =, or > and
@Fredrik, Thanks for the link to the rationale. It looks reasonable. However, in my opinion, more people will need != to be the complement of == behavior most of the time instead of concerning about the low-level stuffs like floating point numbers (especially in such a high-level language like Python).
In Ruby,
!=is always the complement of==. In other words, you can not define your own__ne__method like in Python. There are some drawbacks for this style. For example, in RSpec, you can only use "foo.should_not == bar" but not "foo.should != bar" . But this works fine most of the time.Another (might be better) solution is give the user both control on
__eq__and__ne__but when user defined only one of them on some class, the other automatically become the complement. This seems to violate the explicit over implicit principle of Python. But as Jordan pointed out in that post on comp.lang.python: that principle seems to be a little abused.ps: what do you mean by …and the rest of that post was cut off by wordpress, without warning.? What post do you mean?