Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

How Python Computes the Boolean Value of Objects

Tech 1

Default Truthiness for Instances Without Special Methods

Objects that implement neither __bool__ nor __len__ always evaluate as True in Boolean contexts.

class Packet:
    pass

pkt = Packet()
print(bool(pkt))  # True

Controlling Evaluasion with __bool__

If a class defines __bool__, that method's return value determines the instance's truthiness. Python rqeuires an actual bool return type; otherwise it raises TypeError.

class RetryLimiter:
    def __init__(self, attempts):
        self.attempts = attempts

    def __bool__(self):
        print(f"__bool__ invoked: attempts={self.attempts}")
        self.attempts -= 1
        return self.attempts >= 0

limiter = RetryLimiter(4)
while limiter:
    print("Attempt in progress")
print("No retries left")

# __bool__ invoked: attempts=4
# Attempt in progress
# __bool__ invoked: attempts=3
# Attempt in progress
# __bool__ invoked: attempts=2
# Attempt in progress
# __bool__ invoked: attempts=1
# Attempt in progress
# __bool__ invoked: attempts=0
# No retries left

Flalback to __len__

When __bool__ is missing, the interpreter invokes __len__ if available. A return value of 0 produces False, while any non-zero integer produces True. Like __bool__, this method must return an integer.

class TaskQueue:
    def __init__(self, pending):
        self.pending = pending

    def __len__(self):
        print(f"__len__ invoked: pending={self.pending}")
        self.pending -= 1
        return self.pending

queue = TaskQueue(4)
while queue:
    print("Processing task")
print("Queue empty")

# __len__ invoked: pending=4
# Processing task
# __len__ invoked: pending=3
# Processing task
# __len__ invoked: pending=2
# Processing task
# __len__ invoked: pending=1
# Queue empty

Priority of __bool__ Over __len__

If both methods exist, __bool__ takes precedence and __len__ is ignored during truthiness checks.

class Resource:
    def __init__(self, value):
        self.value = value

    def __bool__(self):
        print(f"__bool__ path: value={self.value}")
        self.value -= 1
        return self.value >= 0

    def __len__(self):
        print(f"__len__ path: value={self.value}")
        self.value -= 1
        return self.value

res = Resource(4)
while res:
    print("Resource available")
print("Resource depleted")

# __bool__ path: value=4
# Resource available
# __bool__ path: value=3
# Resource available
# __bool__ path: value=2
# Resource available
# __bool__ path: value=1
# Resource available
# __bool__ path: value=0
# Resource depleted

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.