Why does __ne__ exist?
Chris Angelico
rosuav at gmail.com
Sun Jan 7 14:55:34 EST 2018
Whoops, premature send. Picking up from the last paragraph.
This is good. This is correct. For inequalities, you can't assume that
>= is the exact opposite of < or the combination of < and == (for
example, sets don't behave like numbers, so "x <= y" is very different
from "x < y or x == y"). But the one that confuses me is != or __ne__.
If you don't create it, you get default behaviour:
>>> class Ham:
... def __eq__(self, other):
... print("%s equals %s" % (self, other))
... return True
...
>>> Ham() == 1
<__main__.Ham object at 0x7fb7557c0278> equals 1
True
>>> 2 == Ham()
<__main__.Ham object at 0x7fb7557c0278> equals 2
True
>>> Ham() != 3
<__main__.Ham object at 0x7fb7557c0278> equals 3
False
>>> 4 != Ham()
<__main__.Ham object at 0x7fb7557c0278> equals 4
False
>>> x = Ham()
>>> x == x
<__main__.Ham object at 0x7fb7557b80f0> equals <__main__.Ham object at
0x7fb7557b80f0>
True
>>> x != x
<__main__.Ham object at 0x7fb7557b80f0> equals <__main__.Ham object at
0x7fb7557b80f0>
False
Under what circumstances would you want "x != y" to be different from
"not (x == y)" ? How would this make for sane behaviour? Even when
other things go weird with equality checks, that basic parallel is
always maintained:
>>> z = float("nan")
>>> z == z
False
>>> z != z
True
Python gives us a "not in" operator that uses __contains__ and then
negates the result. There is no way for "x not in y" to be anything
different from "not (x in y)", as evidenced by the peephole optimizer:
>>> dis.dis("x not in y")
1 0 LOAD_NAME 0 (x)
2 LOAD_NAME 1 (y)
4 COMPARE_OP 7 (not in)
6 RETURN_VALUE
>>> dis.dis("not (x in y)")
1 0 LOAD_NAME 0 (x)
2 LOAD_NAME 1 (y)
4 COMPARE_OP 7 (not in)
6 RETURN_VALUE
So why isn't != done the same way? Is it historical?
ChrisA
More information about the Python-list
mailing list