None
None

Reputation: 3933

Python operators returning ints

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?

Upvotes: 4

Views: 224

Answers (6)

wisty
wisty

Reputation: 7061

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.

Upvotes: 0

alxndr
alxndr

Reputation: 4110

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'

Upvotes: 0

Ishpeck
Ishpeck

Reputation: 2041

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

Upvotes: 1

Greg Hewgill
Greg Hewgill

Reputation: 992787

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)

Upvotes: 1

Thomas Wouters
Thomas Wouters

Reputation: 133405

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.

Upvotes: 1

Ants Aasma
Ants Aasma

Reputation: 54882

You 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?

Upvotes: 3

Related Questions