Is (-1 ==True) True or False? Neither
Oktay Şafak
oktaysafak at superonline.com
Sat Jan 24 20:07:04 EST 2009
Robert Kern wrote:
> On 2009-01-24 17:00, oktaysafak at 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
More information about the Python-list
mailing list