Implicit conversion to boolean in if and while statements

Steven D'Aprano steve+comp.lang.python at pearwood.info
Sun Jul 15 22:38:35 EDT 2012


On Sun, 15 Jul 2012 12:02:37 -0500, Andrew Berg wrote:

> On 7/15/2012 5:56 AM, Steven D'Aprano wrote:
>> 3) Rather than distinguishing "true" from "false", a more useful
>> dichotomy is between "something" and "nothing". Python includes a
>> number of ways of spelling "nothing" of various types, such as:
>> 
>>     None, 0, 0.0, '', [], {}, set()
>> 
>> and nearly everything else is "something".
> Okay, I see the value in this, but I don't understand why None has a
> truth value.

And this is exactly the sort of mental confusion that Laura Crichton 
warned about (see the link I included earlier).

Thinking about "truth values" is harmful, since that's arbitrary. That 
way goes to Javascript, PHP, Ruby etc. that seem to arbitrary pick 
whatever things are truthy or falsey according to some random whim, or 
according to some implementation detail that is meaningless outside of 
the implementation, such as Javascript insisting that while false is 
falsey, if you box it in an object it becomes truthy.

It's crap like that which gives duck-typing bools a bad name.

The distinction you should consider is:

- is it something, or nothing?

(relative to the type in question, of course)

Python (at least the built-ins, third-party code can do any old crap they 
want) is consistent in this. Instances which represent something/non-
emptiness are true, those which represent nothing/emptiness are false.

0? That's the int that represents nothing, so it's false.

23.723? That's one of many floats that represents something, so it's true.

'spam'? That's one of many non-empty strings, so it's true.

''? That's an empty string, that it, it contains nothing, so it is false.

None? That represents a lack of a thing, that is, nothing, so it's false.

(Please don't get into a great philosophical debate over whether 
nothingness is itself something. That impressed me when I was 15. But now 
I know about reification: just because we have a name for a concept 
doesn't mean that the concept is something concrete. None is an object, 
but it *represents* the lack of an object.)


> I would expect None to mean "doesn't exist" or "unknown" or
> something like that - e.g., a value of 0 means 0 jelly beans in the jar
> and None means there isn't a jar.

How you interpret some_variable = None depends on what some_variable 
represents. If some_variable represents "number of jelly beans in a jar", 
then that should be 0 if there is no jar.

If you want to create a language with ternary truth values (yes, no, mu) 
or some larger number (yes, no, maybe, mu, contradiction, unknowable, 
...) be my guest. Just do everyone a favour and do some research on the 
large literature on non-boolean logic systems first.


> FWIW, I have, for a reason I forget, gotten into the habit of writing
> "if x is not None" when testing for None. However, I have not been
> writing "if x is True: ..."/"elif x is False: ..."/"else: 'ruh-roh'"
> when testing for True (in cases where a value of True or False makes
> sense, but any other value would not). Should I?

Only if you want people to laugh at you.

If you *genuinely* want to implement Java in Python, then be explicit 
about your type-testing:

if isinstance(x, bool) and x: ...  

or even 

if type(x) is bool and x: ... # disallow subclasses

Otherwise, where do you stop?

if x is True is True is True is True is True is ... 


Or you could just write idiomatic Python code, including duck-typing, and 
that includes duck-typing bools. Why do you care if somebody calls your 
function with flag=1 instead of flag=True?



-- 
Steven



More information about the Python-list mailing list