Complete guide to Python's __bool__ method covering truth value testing, boolean conversion, and practical examples.
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.
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.
Here’s a simple example showing how to implement bool to control an object’s truthiness. The method must return a boolean value.
basic_bool.py
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.
When bool is not defined, Python uses len as a fallback. This example shows both methods working together.
bool_len.py
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.
bool can be used to implement validation logic, making objects usable in boolean contexts to check their validity.
validation.py
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.
For container-like objects, bool can provide meaningful truthiness based on container state, similar to built-in containers.
container.py
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.
For stateful objects, bool can reflect the current state, making state checks more intuitive and Pythonic.
stateful.py
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.
Return only booleans: bool must return True or False
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
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.