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 returnTrueorFalse - 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.