I mentioned in the previous entry that Python's
bool
class is actually a subclass of
int
(and the
bool
docstring will tell you this if you bother to read it with
help()
before, say, diving into the CPython source code like a system programmer ). Since I was just looking at this, I might as well write down the low-level differences between
int
s and
bool
s. Bools have:
- a custom
__repr__that reportsTrueorFalseinstead of the numeric value; this is also used as the custom__str__forbool.(The code is careful to
internthese strings so that no matter how many times yourepr()orstr()a boolean, only one copy of the literal 'True' or 'False' string will exist.) - a
__new__that returns either the globalTrueobject or the globalFalseobject depending on the truth value of what it's given. - custom functions for
&,|, and^that implement boolean algebra instead of the standard bitwise operations if both arguments are eitherTrueorFalse. Note that eg 'True & 1' results in a bitwise operation and anintobject, even though1is strongly equal toTrue.
That's it.
I'm not quite sure how
bool
blocks being subclassed and I'm not curious enough right now to work it out.
Update: see the comments for the explanation.
The global
True
and
False
objects are of course distinct from what is in effect the global
0
and
1
objects that are all but certain to exist. This means that their
id()
is different (at least in CPython), since the
id()
is the memory address of their C-level object
struct
.
(In modern versions of both CPython 2 and CPython 3 it turns out that global
0
and
1
objects are guaranteed to exist, because 'small integers' between -5 and 257 are actually preallocated as the interpreter is initializing itself.)