bool#

bool is a subclass of int with exactly two instances, True and False. True == 1 and False == 0; both can sit anywhere an int is expected. Anything in Python has a truth value, evaluated when the value appears in a boolean context (if, while, and, or, not).

Falsiness#

Anything is true unless it is one of these.

  • False

  • None

  • Numeric zero (0, 0.0, 0j, Decimal(0)).

  • Empty containers ("", [], {}, set(), b"").

  • Custom objects whose __bool__ returns False, or whose __len__ returns 0.

if items:                 # idiomatic empty-check
    process(items)

if not items:             # idiomatic empty-check, negated
    return

if config.get("port") or 8080:
    ...

if items: is the idiomatic empty-check; if items == []: reads as a junior tell.

Short-circuit#

and and or return one of the operands (not a coerced boolean) and stop as soon as the result is known.

x = value or default      # `or` returns the first truthy operand
y = value and other       # `and` returns the first falsy or last
        flowchart LR
    A["x and y"] --> B{"truthy(x)?"}
    B -->|false| C["return x"]
    B -->|true| D["return y"]
    

This is the basis for the common defaulting idiom host = host or 'localhost' and for chained guards user and user.is_admin and grant_access().

Methods#

bool inherits every int method (see int). The methods specific to truthiness are operators and built-ins, not methods on the instance.

Call

Effect

bool(x)

Apply the truthiness rules to x.

x and y

Short-circuit AND; returns x if falsy, else y.

x or y

Short-circuit OR; returns x if truthy, else y.

not x

Logical negation; always returns bool.

all(iterable)

True when every element is truthy (or iterable is empty).

any(iterable)

True when at least one element is truthy.

bool applies the truthiness rules to any value.

bool(""), bool("x"), bool([]), bool([0])
(False, True, False, True)

and / or short-circuit and return one of the operands, not a coerced boolean.

0 or "default", "" or None or "fallback"
('default', 'fallback')

all and any collapse an iterable of booleans.

all([1, 2, 3]), any([0, 0, ""])
(True, False)

Operator overloading#

bool inherits every dunder from int (see int); the operators on it dispatch through those. and, or, and not are not overloadable; they are short-circuit syntactic forms, not dunder calls. The closest hook is __bool__ (the truthiness predicate).

Operator

Dunder

Returns

bool(x)

__bool__

Truthiness of x.

a == b

__eq__ (from int)

Equality.

a & b

__and__ (from int)

Bitwise AND (often useful for boolean masks).

a | b

__or__ (from int)

Bitwise OR.

a ^ b

__xor__ (from int)

Bitwise XOR.

and, or, not are language keywords; they cannot be overloaded by overriding a dunder. Reach for __bool__ to control how a custom type behaves in a boolean context.

A container class can use __bool__ so if container: follows its own emptiness rule.

class Bag:
    def __init__(self, items): self.items = list(items)
    def __bool__(self): return bool(self.items)

bool(Bag([])), bool(Bag([1]))
(False, True)

__len__ is the fallback when __bool__ is absent; Python calls len and treats zero as False.

class Bag:
    def __init__(self, items): self.items = list(items)
    def __len__(self): return len(self.items)

bool(Bag([])), bool(Bag([1, 2]))
(False, True)

References#