I don’t understand how the code in the for loop knows whether the instance of the class is truthy or not. My understanding is probably faulty but what I think is happening is this: the call to bool calls the altered special method bool which has been modified to use the len built in on the instance. But outside of the class, when we get to the for loop and the if conditional I don’t know how “if” knows whether the order is truthy unless it is calling the special method bool(behind the scenes).
I apologise if this is not the forum for such a question but I don’t know enough of the required terminology to find an answer to this on google or a good book to get my head around OOP with a python bias.
Code
class Order:
def __init__(self, cart, customer):
self.cart = list(cart)
self.customer = customer
# def __bool__(self):
#print("\'__bool__ got called\'")
#return len(self.cart) > 0
order1 = Order(['banana', 'apple', 'mango'], 'Real Python')
order2 = Order([], 'Python')
for order in [order1, order2]:
if order:
print(f"{order.customer}'s order is processing...")
else:
print(f"Empty order for customer {order.customer}")
print(bool(order2))
Please refer Python3 docs
In short, your object's base class has a __bool__
function that can be implemented to define truthfulness.
If it's not defined on the type, then the base class implementation will be called.
It functions as you said, by calling __len__
.
If neither __bool__
nor __len__
are defined, all the class objects are considered true.
Edit to my answer with @chepner's contribution from the comments:
In order to evaluate bool(Order()), Python tries to:
Order.__bool__
,__bool__
for some parent class.Order.__len__
,__len__
.bool(Order())
simply returns True
.