Friday, June 5, 2026

How does Python’s handling of len() differ for built-in types vs. custom classes?

All Questions From This Chapter    « Previously    Next »

len() behaves similarly at the language level for both built-in types and custom classes — it looks for a special method called __len__() — but there are important implementation differences.

1. Built-in types: optimized, implemented in C

For built-in objects like list, str, tuple, dict, etc., length is usually:

  • Stored internally as metadata

  • Implemented in C for speed

  • Retrieved in O(1) time

Example:

Python
a = [1, 2, 3]
print(len(a)) # 3

Internally, Python does not iterate through the list each time. The list object already stores its size.


2. Custom classes: you provide __len__()

For your own classes, len(obj) calls:

Python
obj.__len__()

Example:

Python
class MyCollection:
def __init__(self, items):
self.items = items

def __len__(self):
return len(self.items)

c = MyCollection([10, 20, 30])
print(len(c)) # 3

Equivalent behavior:

Python
print(c.__len__())

3. If __len__() is missing

Python raises a TypeError.

Python
class A:
pass

a = A()
print(len(a))

Output:

TypeError: object of type 'A' has no len()

4. Rules for __len__()

Your __len__() method must return:

  • an integer

  • ≥ 0

Bad examples:

Python
class Bad:
def __len__(self):
return -1

len(Bad())

Output:

ValueError: __len__() should return >= 0

Or:

Python
class Bad:
def __len__(self):
return "five"

Output:

TypeError

5. Relationship with truthiness

If __bool__() is absent, Python uses __len__():

Python
class Box:
def __len__(self):
return 0

b = Box()

print(bool(b)) # False

Rule:

__bool__() → preferred
otherwise __len__()
otherwise True

6. Important internal difference: special method lookup

For special methods like __len__, Python does not always use normal instance attribute lookup.

This fails:

Python
class A:
pass

a = A()
a.__len__ = lambda: 5

len(a) # Error

Because Python looks up __len__ on the class, not the instance.

This works:

Python
class A:
def __len__(self):
return 5

a = A()
print(len(a)) # 5

Summary

AspectBuilt-in TypesCustom Classes
Where length logic livesC implementationYour __len__()
PerformanceUsually O(1)Depends on implementation
Need to define length?Already definedMust implement __len__()
Missing length behaviorRareTypeError
Truthiness fallbackUses internal lengthUses your __len__()

The key takeaway: len(x) always tries the object's length protocol (__len__), but built-in types have highly optimized internal implementations while custom classes must explicitly provide that behavior.


All Questions From This Chapter    « Previously    Next »

No comments:

Post a Comment