Equivalent code to the bool() built-in function

Steven D'Aprano steve+comp.lang.python at pearwood.info
Mon Apr 18 02:22:53 CEST 2011


On Mon, 18 Apr 2011 01:22:59 +0200, candide wrote:

>  > What is the
>  > “shortcut” you refer to?
> 
> bool(x) is nothing more than a shortcut for the following expression :
> True if x else False.

"Nothing more"? That's completely incorrect. bool is a type object, not 
an expression, so you can do things like these:

>>> isinstance("Hello world", (float, bool))
False

>>> issubclass(bool, list)
False

>>> types = [str, complex, float, bool]
>>> [f(x) for f, x in zip(types, (1, 2, 3, 4))]
['1', (2+0j), 3.0, True]


For that reason alone, bool is useful.



> Compare for instance with the str() type whose implementation is far
> more complicated.

So what? What's your point? Types and functions don't exist because 
they're *complicated*, but because they're *useful*. bool is useful: 
in order for True and False to print as True and False, they need to 
belong to a type that has that behaviour. bool is that type.

Consequently, calling bool(x) returns a canonical True/False from any 
arbitrary object, but that's not the primary purpose for bool existing.



> When learning Python, you early and communly use str()
> type but use sparingly the bool() type.

So what? What's your point?


A little bit of history may make things more clear to you.

Up to version 2.1, Python had no built-in True and False values. This 
*almost always* worked fine, since you can always say (e.g.):

if x:
    do_something()
elif y or z:
    do_something_else()

for any objects x, y and z. But it wasn't quite ideal, because:

* if flags are written 0 and 1, that frequently fools people into
  thinking they are meant to be understood as *integer* values rather 
  than boolean values, and they will do arithmetic on those flags;
* people coming from other languages were confused and worried by 
  the lack of bools and found it difficult to get used to the 
  Python truth-testing idiom;
* people would define a standard pair of True/False values at the 
  top of each module, so they could refer to flags by name rather
  than value;
* there was never any consistency, people would write any of:

  true = 1; false = 0
  FALSE = 0; TRUE = not FALSE
  True = -1; False = not True

  or whatever other idiom they preferred, or they'd write custom 
  classes that printed as true/TRUE/True etc.


So in Python 2.2, Python introduced two new built-in names, True and 
False, with values 1 and 0 respectively:

[steve at sylar ~]$ python2.2
Python 2.2.3 (#1, Aug 12 2010, 01:08:27)
[GCC 4.1.2 20070925 (Red Hat 4.1.2-27)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> True, False
(1, 0)
>>> type(True)
<type 'int'>


Then in Python 2.3, Python introduced the bool type, which gave True and 
False an independent type ("bool") with a prettier display. For backwards 
compatibility reasons, bool is actually a subclass of int, so that code 
that does arithmetic on flags continues to work.

The ternary if operator `true-value if flag else false-value` wasn't 
introduced until version 2.5.

So as you can see, while you are correct *today* that the function call 
"bool(x)" is equivalent to "True if x else False", for at least seven 
versions of Python (1.4, 1.5, 1.6, 2.0 through 2.4) that was not correct.

Furthermore, why would you write "True if x else False" (twenty 
characters) instead of "bool(x)" (seven characters)? bool is the 
canonical way to get an explicit boolean value. It's even shorter than 
"not not x" (nine characters), and far more obvious than either of the 
alternatives.

You're also correct that there very rarely is a need to explicitly 
convert arbitrary objects to booleans. That's okay. That's not why bool 
exists, that's just an occasionally useful side-effect.



-- 
Steven



More information about the Python-list mailing list