Search code examples
pythontruthiness

Why can we cast bool to str?


We know how bool() acts on various python objects such as str, int, list.

This is a question about the reverse.

You can cast bool to int as

>>> int(True)
1
>>> int(False)
0

which I think kinda makes sense, but with string we get

>>> str(False)
'False'
>>> str(True)
'True'

which I don't get, as firstly it seems to imply some relation between False and 'False', which only seems relevant at the code level. If what is written in code is to be treated this way, how does this work ...

>>> str(not True)
'False'

Second, it's not obvious it's for consistency, as

>>> bool(str(False))
True

My question is ... is there a reason we're allowed to cast bool to str in this way? list for example won't allow it ...

>>> list()
[]
>>> bool()
False
>>> bool(list())
False
>>> list(bool())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'bool' object is not iterable

Solution

  • For debugging. If you can't cast a thing to a string, you can't print it. If you want to print a data structure for debugging, you need to be able to cast each element to a string. That's what str is documented to do...

    Return a string containing a nicely printable representation of an object.


    If what is written in code is to be treated this way, how does this work ...

    >>> str(not True)
    'False'
    

    not True resolves to False which is then passed to str. It's similar to how with foo(1 + 1) foo receives 2.


    Second, it's not obvious it's for consistency, as

    >>> bool(str(False))
    True
    

    Casting is not guaranteed to round trip. Examples are int(float(2.34)) or int(unichr(97)).

    There's an important difference between converting something to a string for humans, which is what str does, and converting something to a string for marshalling which must round trip. There are specialized packages like marshal or json for marshalling.

    But casting is the wrong way to think about bool and str in Python. As above, str returns a printable representation, not a machine-readable one. bool is for asking "what is the truthiness of this expression"? From the docs...

    x is converted using the standard truth testing procedure.

    "True" and "False" are both true. If they added a special case just for bool that would be very inconsistent.