"""
Program: Demonstrate how to print class instances with custom output.
Notes:
------
- __str__ is used by print().
- __repr__ is used by the interpreter and debugging tools.
- Both methods are made robust so missing attributes won't crash the program.
"""
class Test:
"""A simple class with a custom string representation."""
def __init__(self, a="foo"):
self.a = a
def __repr__(self):
"""
Developer-facing representation.
Must never crash, even if attributes are missing.
"""
try:
return f"Test(a={self.a!r})"
except AttributeError:
return "Test(a=<unknown>)"
def __str__(self):
"""
User-facing representation for print().
Also made safe against missing attributes.
"""
try:
return f"Test instance with a='{self.a}'"
except AttributeError:
return "Test instance with a=<unknown>"
def safe_print(obj):
"""
Demonstrates safe printing:
- If __str__ fails, fallback to __repr__.
"""
try:
print(obj)
except Exception:
print("__str__ failed; falling back to __repr__:", repr(obj))
def main():
print("Test case 1:")
t1 = Test()
safe_print(t1)
print("repr:", repr(t1))
print()
print("Test case 2:")
t2 = Test("bar")
safe_print(t2)
print("repr:", repr(t2))
print()
print("Test case 3:")
t3 = Test("")
safe_print(t3)
print("repr:", repr(t3))
print()
print("Test case 4:")
t4 = Test("baz")
del t4.a # simulate missing attribute
safe_print(t4)
print("repr:", repr(t4))
print()
print("Test case 5:")
items = [Test("alpha"), Test("beta"), Test("gamma")]
for item in items:
safe_print(item)
print()
if __name__ == "__main__":
main()
"""
run:
Test case 1:
Test instance with a='foo'
repr: Test(a='foo')
Test case 2:
Test instance with a='bar'
repr: Test(a='bar')
Test case 3:
Test instance with a=''
repr: Test(a='')
Test case 4:
Test instance with a=<unknown>
repr: Test(a=<unknown>)
Test case 5:
Test instance with a='alpha'
Test instance with a='beta'
Test instance with a='gamma'
"""