__str__, __repr__, __len__
__str__, __repr__, and __len__
In Python, the way objects display themselves to developers and end users—as well as how their size is evaluated—is governed by foundational dunder methods: __repr__, __str__, and __len__. Implementing these methods thoughtfully ensures that your custom data structures integrate seamlessly with logging frameworks, interactive debuggers, formatted strings, and built-in Python functions.
1. __repr__ vs __str__: The Core Distinction
Python provides two distinct string representation mechanisms. While they appear similar on the surface, they serve fundamentally different audiences and purposes.
Purpose Comparison
| Feature | __repr__ (Representation) | __str__ (String) |
|---|---|---|
| Audience | Software engineers, maintainers, debuggers | End users, reports, UI displays |
| Goal | Unambiguous; ideally valid Python code to recreate the object | Readable, clean, human-friendly presentation |
| Fallback | Defaults to <ClassName object at 0x...> if unhandled | Falls back to __repr__ automatically if omitted |
| Invocation | repr(x), REPL output, interactive debugger, %r, !r | str(x), print(x), f"{x}", format(x) |
Practical Rule of Thumb
__repr__ first. If you only implement __repr__, Python uses it as the default fallback for __str__. If you only implement __str__, the object will still display the unhelpful <ClassName object at 0x...> in lists, dictionaries, tracebacks, and interactive shells.2. Implementing __repr__ and __str__
Here is an architectural pattern for implementing both methods in a domain entity:
3. The __len__ Protocol and Truthiness
The __len__ method hooks into the built-in len(object) function. It is part of the Sequence Protocol and the Mapping Protocol.
Strict Requirements for __len__
- 1Must return a non-negative integer (
int >= 0). - 2Returning a negative integer raises a
ValueError: __len__() should return >= 0. - 3Returning a non-integer (such as a float or string) raises a
TypeError: 'float' object cannot be interpreted as an integer. - 4If a class does not define
__bool__, Python evaluates truthiness using__len__(): iflen(obj) == 0, the object is evaluated asFalse; otherwise, it evaluates toTrue.
4. Complementary Methods: __format__ and __bytes__
In addition to standard string rendering, Python provides specialized representations:
__format__(self, format_spec: str)
Called by format(obj, spec) or f-string specifiers f"{obj:spec}".
Visual Architecture & Process Flow
How data and code flow step-by-step
5. Architectural Comparison Summary
| Method | Built-in Caller | Type Constraint | Primary Use Case |
|---|---|---|---|
__repr__ | repr(x) | Must return str | Debugging, inspection, recreating the object |
__str__ | str(x), print(x) | Must return str | User-friendly UI / logging strings |
__len__ | len(x) | Must return int >= 0 | Size measurement, truthiness fallback |
__format__ | format(x, spec) | Must return str | Custom formatting specifications |
__bytes__ | bytes(x) | Must return bytes | Binary serialization |
Multiple Choice Questions
1.
What happens when you execute print(obj) on an instance of a class that defines __repr__ but DOES NOT define __str__? A. Python raises an AttributeError indicating missing __str__. B. Python falls back to executing __repr__. C. Python prints the default memory pointer address. D. Python outputs an empty string.
__str__ is not implemented on a class, calls to str(obj) and print(obj) automatically fall back to invoking __repr__.2.
Which of the following describes the ideal standard design guideline for __repr__? A. It should return a translated string localized to the user's operating system language. B. It should return an unambiguous string that, whenever feasible, is valid Python code capable of recreating the object. C. It must return a unique memory address integer. D. It should only display private attributes prefixed with double underscores.
__repr__ is to be unambiguous and, whenever practical, match the expression that could be passed to eval() or executed in Python code to recreate the object.3.
When an instance is contained inside a standard Python list, how is each item displayed when the entire list is printed via print([item1, item2])? A. Using item.__str__() B. Using item.__repr__() C. Using item.__format__() D. Using item.__bytes__()
__repr__ method, not __str__.4.
What will happen if a custom __len__ method returns a negative integer like -5? A. Python converts it to an absolute value (5). B. Python treats the object as having length 0. C. Python raises a runtime ValueError. D. Python raises an OverflowError.
__len__() must return a non-negative integer (>= 0). Returning a negative number triggers a ValueError: __len__() should return >= 0.5.
If an object does not define a __bool__ method, how does Python determine its boolean truthiness in an if obj: conditional check? A. It always defaults to False. B. It calls __len__(); if the length is 0, it is False, otherwise True. If __len__ is also absent, it defaults to True. C. It calls __repr__() and checks if the resulting string is non-empty. D. It raises a TypeError.
__bool__, Python checks for __len__. If __len__ is defined, the object is truthy if length is non-zero. If neither method is defined, all instances of user-defined classes are considered truthy (True).Operator Overloading
Continue learning with hands-on practice, examples, and exercises in the upcoming topic.
Related Lessons
| Previous Lesson | Next Lesson |
|---|---|
| Introduction to Dunder Methods | Operator Overloading |
Practice Quiz
Test your understanding of this lesson with 5 questions. Each question has one correct answer.