Booleans, Truthiness, and Short-Circuit Logic
Booleans, Truthiness, and Short-Circuit Logic
After reading this chapter, you will master Python’s bool type, the exact rules of truth value testing (truthiness), and how short-circuit evaluation powers defensive programming idioms.
Mental model
In Python, bool is an explicit subclass of int. There are only two instances: True and False.
┌────────────────┐
│ class 'int' │
└───────┬────────┘
│ inherits
┌───────▼────────┐
│ class 'bool' │
└───────┬────────┘
│
┌─────────────┴─────────────┐
▼ ▼
True (int value: 1) False (int value: 0)
Every Python object can be evaluated in a boolean context (such as an if statement or while loop). The language defines a specific set of falsy values; every other object in Python is considered truthy.
Falsy Objects:
- Constants: None, False
- Zero numbers: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
- Empty sequences: "", (), [], b"", bytearray(b"")
- Empty collections/mappings: {}, set(), frozenset()
- Custom objects defining __bool__() returning False, or __len__() returning 0
Minimal example
Save as truthiness_demo.py:
# truthiness_demo.py
def main() -> None:
falsy_values = [None, False, 0, 0.0, "", [], {}, set()]
print("Checking standard falsy values:")
for item in falsy_values:
print(f"bool({repr(item):10s}) -> {bool(item)}")
# Short-circuit returns the deciding operand, not necessarily a boolean!
val1 = "fallback_host" or "default"
val2 = "" or "fallback_host"
print(f"\nval1: {val1}")
print(f"val2: {val2}")
if __name__ == "__main__":
main()Run via uv run python truthiness_demo.py:
Checking standard falsy values:
bool(None ) -> False
bool(False ) -> False
bool(0 ) -> False
bool(0.0 ) -> False
bool('' ) -> False
bool([] ) -> False
bool({} ) -> False
bool(set() ) -> False
val1: fallback_host
val2: fallback_host
Worked examples
Case 1: Short-circuit evaluation as a safety guard
The and operator evaluates left-to-right; if the left operand is falsy, it immediately aborts evaluation and returns that operand. This allows writing safe guards:
# guard_demo.py
class DeviceConnection:
def __init__(self, connected: bool) -> None:
self.connected = connected
def query_stats(self) -> str:
return "CPU: 12%, Temp: 41C"
def check_device(dev: DeviceConnection | None) -> None:
# Guard against None, then check connected attribute
if dev is not None and dev.connected:
print(f"Device live: {dev.query_stats()}")
else:
print("Device unavailable or offline")
if __name__ == "__main__":
check_device(None)
check_device(DeviceConnection(connected=False))
check_device(DeviceConnection(connected=True))Run:
uv run python guard_demo.pyCase 2: The conditional ternary expression
Python supports inline ternary expressions: value_if_true if condition else value_if_false:
# ternary_demo.py
def get_env_concurrency(is_prod: bool) -> int:
workers = 32 if is_prod else 4
return workers
if __name__ == "__main__":
print(f"Development workers: {get_env_concurrency(is_prod=False)}")
print(f"Production workers : {get_env_concurrency(is_prod=True)}")Run:
uv run python ternary_demo.pyPitfalls
Pitfall 1: Fallback idiom swallowing valid falsy values
# Dangerous when 0 or False is a legitimate user configuration value:
timeout = config.get("timeout") or 30 # If timeout was configured as 0, it gets replaced by 30!
# Correct fix:
timeout = config["timeout"] if "timeout" in config and config["timeout"] is not None else 30Pitfall 2: Explicit comparison with True or False
Never write if is_ready == True: or if is_ready is True:. Idiomatic Python simply writes if is_ready:.
Exercises
- Create a custom class
ServerPoolthat evaluates toFalsein a boolean context when its internal server list is empty, andTruewhen it has at least one server, using__bool__(). - Trace the exact return value of:
"" and "hello","hello" and "world",[] or 0 or "default". Verify by running in a script. - Write a validator function
is_valid_payload(payload: dict) -> boolthat checks if the dictionary is non-empty and contains required keys"id"and"timestamp"using short-circuit boolean logic.
Further reading
- Python Language Reference: Section 6.11: Boolean operations.
- Python Standard Library: Truth Value Testing.
- PEP 285: Adding a bool type.