"0 in [True,False]" returns True

Steve Holden steve at holdenweb.com
Tue Dec 13 05:03:18 EST 2005


Antoon Pardon wrote:
> Op 2005-12-13, Steve Holden schreef <steve at holdenweb.com>:
> 
>>Pierre Quentel wrote:
>>
>>>Hi all,
>>>
>>>In some program I was testing if a variable was a boolean, with this 
>>>test : if v in [True,False]
>>>
>>>My script didn't work in some cases and I eventually found that for v = 
>>>0 the test returned True
>>>
>>>So I changed my test for the obvious "if type(v) is bool", but I still 
>>>find it confusing that "0 in [True,False]" returns True
>>>
>>>By the way, I searched in the documentation what "obj in list" meant and 
>>>couldn't find a precise definition (does it test for equality or 
>>>identity with one of the values in list ? equality, it seems) ; did I 
>>>miss something ?
>>>
>>
>>It actually uses the __contains__() method of the right-hand operand, 
>>and in the case of a list that will test for equality of the left-hand 
>>operand to one of the list elements. Since False == 0 that's why you see 
>>what you do.
>>
>>The really interesting question your post raises, though, is "Why do you 
>>feel it's necessary to test to see whether a variable is a Boolean?".
> 
> 
> I can give you one example. I have written a tube class. A tube behaves
> like Queue but it has additional code so that it can be registed with
> gtk in the same way as file descriptor can be registered with
> io_add_watch. The way this is implemented is by registering an idle
> handler when the tube is not empty and removing it when the tube is
> empty. So I have a variable cb_src (for callback source) that can be
> a boolean or an integer. The possible values are
> 
>   False: Not registered by the user
>   True: Registered by the user but no nternal idle callback registerd
>   a number: gtk integer ID, from the registered idle callback handler.
> 
Well I guess you'd better hope that gtk never returns a zero or one, then.

Note, though, that True and False are defined to be singleton instances, 
so it *is* permissible to say

     if i is False:

 >>> 0 is False
False
 >>> 1 is True
False
 >>>

However I must say the coupling in that interface has a very definite 
code smell. Why not use two variables, a Boolean "registered" and an 
integer ID that is meaningless when registered is False?

regards
  Steve
-- 
Steve Holden       +44 150 684 7255  +1 800 494 3119
Holden Web LLC                     www.holdenweb.com
PyCon TX 2006                  www.python.org/pycon/




More information about the Python-list mailing list