Python __bool__ Method
Last modified April 8, 2025
This comprehensive guide explores Python's __bool__
method, the
special method that defines an object's truth value. We'll cover basic usage,
truthiness rules, practical examples, and common patterns.
Basic Definitions
The __bool__
method is called to implement truth value testing
and the built-in bool()
function. It should return True
or False
.
When __bool__
is not defined, Python falls back to __len__
.
If neither is defined, objects are considered True
by default.
This method is crucial for control flow statements.
Basic __bool__ Implementation
Here's a simple example showing how to implement __bool__
to
control an object's truthiness. The method must return a boolean value.
class Account: def __init__(self, balance): self.balance = balance def __bool__(self): return self.balance > 0 account1 = Account(100) account2 = Account(-50) print(bool(account1)) # True print(bool(account2)) # False if account1: print("Account has funds")
This example defines an Account
class where an account is
considered truthy if its balance is positive. The __bool__
method encapsulates this business logic.
The method is automatically called when the object is used in a boolean
context, like if
statements or with the bool()
function.
__bool__ with __len__ Fallback
When __bool__
is not defined, Python uses __len__
as a fallback. This example shows both methods working together.
class ShoppingCart: def __init__(self, items): self.items = items def __len__(self): return len(self.items) def __bool__(self): return any(item.price > 0 for item in self.items) class Item: def __init__(self, price): self.price = price cart1 = ShoppingCart([Item(10), Item(20)]) cart2 = ShoppingCart([Item(0), Item(0)]) print(bool(cart1)) # True (__bool__ returns True) print(bool(cart2)) # False (__bool__ returns False) print(bool(ShoppingCart([]))) # False (__len__ returns 0)
This example shows that __bool__
takes precedence over
__len__
. For empty carts, Python falls back to __len__
when __bool__
isn't defined.
The cart is considered truthy only if it contains at least one item with a positive price, demonstrating custom truthiness logic.
Truthiness in Data Validation
__bool__
can be used to implement validation logic, making
objects usable in boolean contexts to check their validity.
class UserProfile: def __init__(self, name, email): self.name = name self.email = email self._validate() def _validate(self): self.is_valid = ( isinstance(self.name, str) and '@' in self.email ) def __bool__(self): return self.is_valid valid_user = UserProfile("Alice", "alice@example.com") invalid_user = UserProfile(123, "bobexample.com") print(bool(valid_user)) # True print(bool(invalid_user)) # False if not invalid_user: print("Profile is invalid")
This example uses __bool__
to expose validation status. The
method returns the internal is_valid
flag set during
initialization.
This pattern is useful when you want objects to self-report their validity in a natural way through boolean testing.
Custom Container Truthiness
For container-like objects, __bool__
can provide meaningful
truthiness based on container state, similar to built-in containers.
class Playlist: def __init__(self, songs): self.songs = list(songs) def __bool__(self): return len(self.songs) > 0 and any( song.duration > 0 for song in self.songs ) def __len__(self): return len(self.songs) class Song: def __init__(self, duration): self.duration = duration empty_playlist = Playlist([]) playlist_with_silent_tracks = Playlist([Song(0), Song(0)]) valid_playlist = Playlist([Song(180), Song(240)]) print(bool(empty_playlist)) # False print(bool(playlist_with_silent_tracks)) # False print(bool(valid_playlist)) # True
This Playlist
class is only considered truthy if it contains
songs with positive duration. It combines length check with content
validation.
The implementation follows Python's principle that empty containers are falsey, but extends it with domain-specific logic about what constitutes a "valid" playlist.
__bool__ in Stateful Objects
For stateful objects, __bool__
can reflect the current state,
making state checks more intuitive and Pythonic.
class TrafficLight: def __init__(self): self._state = 'red' def change(self): if self._state == 'red': self._state = 'green' elif self._state == 'green': self._state = 'yellow' else: self._state = 'red' def __bool__(self): return self._state == 'green' light = TrafficLight() print(bool(light)) # False light.change() print(bool(light)) # True light.change() print(bool(light)) # False
This traffic light implementation uses __bool__
to indicate
whether the light is green. The boolean value changes as the light's
state changes.
This pattern makes code more readable when checking object state, as
if light:
clearly expresses the intent to check for the
green state.
Best Practices
- Return only booleans:
__bool__
must returnTrue
orFalse
- Keep it simple: Truthiness should be obvious and predictable
- Consider
__len__
: For collections, define both methods appropriately - Document behavior: Clearly document your truthiness rules
- Follow Python conventions: Empty collections should be falsey
Source References
Author
List all Python tutorials.