Is there any way to have Python operators line "==" and ">" return ints instead of bools. I know that I could use the int function (int(1 == 1)
) or add 0 ((1 == 1) + 0
) but I was wondering if there was an easy way to do it. Like when you want division to return floats you could type from __future__ import division
. Is there any way to do this with operators returning ints? Or could I make a class extending __future__._Feature
that would do what I want?
views:
105answers:
6You cant override the built-in comparison functions. In some sense the comparison operators are already returning int
. bool
is a subclass of int
, so you can do anything to it that you can do to a int. The question then becomes why would you want to have comparisons return int objects, not bool objects?
You can have the comparison operators of your custom classes return whatever you like -- simply implement the relevant methods (__eq__
, __ne__
, __gt__
, __lt__
, __ge__
, __le__
) to return what you want. For objects that you don't control you cannot change this, but there should be no need to: bools are ints, because of the Liskov substitution principle. Code that notices a difference between the bool returned by the builtin types' __eq__
methods and any other integer is using the result wrong.
The __future__
module isn't relevant here; you can't use it to do whatever you want, you can only use it to change specific settings that were added to Python. You can turn division into true division with the __future__
import because that's what was added to Python. The only way to add more __future__
imports is by modifying Python itself.
Based on your clarification, you might change your comparison operator to something like:
stack.push(1 if stack.pop() > stack.pop() else 0)
This will convert the boolean result of >
to 1
or 0
as you would like.
Also, be careful about calling stack.pop()
twice in the same expression. You don't know (for sure) what order the arguments will be evaluated in, and different implementations of Python may very well pop the arguments in a different order. You will need to use temporary variables:
x = stack.pop()
y = stack.pop()
stack.push(1 if x > y else 0)
On your own objects, it is easy to override each comparison operator. For built-ins, the override methods are "read only" so all my attempts to set them don't pan out.
>>> class foo:
def __lt__(self, other):
return cmp(5, other)
>>> f = foo()
>>> f<3
1
>>> f<7
-1
>>> f<5
0
>>> j=""
>>> j.__lt__=lambda other: cmp(5, other)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'str' object attribute '__lt__' is read-only
Cast your bool to an int?
>>> int(True)
1
>>> int(False)
0
Or cast that to a str?
>>> str(int(True))
'1'
>>> str(int(False))
'0'
No, you can't. When Guido unified types and classes, he found a way to override the behavior of built-in types (due to the way he implemented things), but he declared it a bug and plugged the loophole. Changing the behavior of built-in types (except for your example - importing division from future, which is there for a good reason) is forbidden.
Sorry, but I can't find the mailing list post. I remember it though, as it was quite interesting.