Robert Kern wrote:
On 2009-01-24 17:00, oktaysa...@superonline.com wrote:
Hi all,

I ran into a strange case.

Python 2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit
(Intel)] on win32
...
 >>> -1 == True
False
 >>> -1 == False
False

This works though:
 >>> if -1:
print "OK"

OK

After some head scratching, I realized that:
- bool is a subclass of int and that True and False evaluates to 1 and
0, so -1 is equal to neither; and
- The if -1: statement probably works by treating -1 as bool(-1).

Yes.

Good.


But I can't help finding the former comparison behavior odd. I admit
that it is odd to write such code but when someone writes -1 == True,
the intention is clearly a boolean comparison, not a numerical value
comparison, isn't it?

Not to me. The rules of Python state that the object on the left hand side is asked first how to compare the two values. Only if that fails is the object on the right hand side asked how to compare the objects.

OK.

As far as I understand, to do this comparison, python is casting
(loosely speaking) True to its numerical value, rather than casting -1
to its boolean value.

Not really. No casting goes on at all.

Of course, I said loosely speaking.

bool is just one of the types that int.__eq__ knows how to handle because bool is a subclass of int. Vice-versa, bool.__eq__ knows how to handle ints, and it also does a numerical comparison; it never casts to a boolean.

That's what I'm trying to say: it would be more meaningful if int.__eq__ did a boolean comparison when the other operand is a boolean. And bool.__eq__ should as well do a boolean comparison when the other operand is an integer (or even a number). The reason is that when someone writes (-1 == True) he is clearly, definitely, absolutely asking for a boolean comparison, not a numerical one. As I said before, this is weird code; but using the True built-in for checking whether a number's value is equal to 1 would be even weirder.


So, my question is: wouldn't it make more sense to do just the opposite,
i.e. cast -1 to its boolean value and do a boolean comparison of the
operands, when one of the operands is True or False?

Or is this too fancy? What do you think?

I think that being explicit is better than being implicit.

Well, I agree that explicit is better than implicit: when one wants to use the numerical values of True or False, he should make it explicit and use int(True) or int(False), but one is never interested in a boolean's numerical value (which is nonsense, IMHO). We never write counter += True, for example.

If you want to cast an object to a boolean, use bool() on it.

Well, I can tell you in response that if you are interested in a boolean's *integer* value, than make it explicit and use int(True). When I write

assert i == True

I'm not trying to make sure that i is equal to one, I am trying to make sure that it evaluates to True (of course True is redundant here but it can make the code more readable). If I was interested in the former case, it would be most natural to write assert i == 1 but I'm interested in the latter and I think Python's treatment is not quite right here.

> Making special rules when comparing with booleans makes it harder to
> treat True and False as first-class objects.

I don't see how fixing this makes harder to treat True and False as first-class objects. If doing the right thing takes some special casing then be it, but I don't think it's so.

Anyway, thanks for the response.

Oktay
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to