11.2. OOP Repr
Typing
obj
into REPL (console) callsrepr(obj)
Calling
repr(obj)
callsobj.__repr__()
Method
obj.__repr__()
must returnstr
Intended for developers of your class
Shows object representation
Copy-paste for creating object with the same values
Useful for debugging
Printing
list
will call__repr__()
method on each element
11.2.1. Default
Object without
__repr__()
method overloaded prints their memory address
>>> class User:
... def __init__(self, username, password):
... self.username = username
... self.password = password
>>>
>>>
>>> alice = User('alice', 'secret')
>>>
>>> alice
<__main__.User object at 0x...>
>>>
>>> repr(alice)
'<__main__.User object at 0x...>'
>>>
>>> alice.__repr__()
'<__main__.User object at 0x...>'
>>>
>>> f'Hello {alice!r}'
'Hello <__main__.User object at 0x...>'
11.2.2. Overloaded
Not all information needs to be printed, ie. passwords
>>> class User:
... def __init__(self, username, password):
... self.username = username
... self.password = password
...
... def __repr__(self):
... username = self.username
... password = '******'
... return f'User({username=}, {password=})'
>>>
>>>
>>> alice = User('alice', 'secret')
>>>
>>> alice
User(username='alice', password='******')
>>>
>>> repr(alice)
"User(username='alice', password='******')"
>>>
>>> alice.__repr__()
"User(username='alice', password='******')"
>>>
>>> f'Hello {alice!r}'
"Hello User(username='alice', password='******')"
11.2.3. Inheritance
Problem:
>>> class User:
... def __init__(self, username, password):
... self.username = username
... self.password = password
...
... def __repr__(self):
... username = self.username
... password = '******'
... return f'User({username=}, {password=})'
>>>
>>>
>>> class Admin(User):
... pass
>>>
>>>
>>> alice = User('alice', 'secret')
>>> bob = Admin('bob', 'qwerty')
>>>
>>> alice
User(username='alice', password='******')
>>>
>>> bob
User(username='bob', password='******')
Solution:
>>> class User:
... def __init__(self, username, password):
... self.username = username
... self.password = password
...
... def __repr__(self):
... clsname = self.__class__.__name__
... username = self.username
... password = '******'
... return f'{clsname}({username=}, {password=})'
>>>
>>>
>>> class Admin(User):
... pass
>>>
>>>
>>> alice = User('alice', 'secret')
>>> bob = Admin('bob', 'qwerty')
>>>
>>> alice
User(username='alice', password='******')
>>>
>>> bob
Admin(username='bob', password='******')
11.2.4. Nested
Printing
list
will call__repr__()
method on each element
>>> data = [1,2,3]
>>>
>>> print(data)
[1, 2, 3]
>>> class User:
... def __init__(self, username): ...
... def __repr__(self): return 'repr'
... def __str__(self): return 'str'
>>>
>>> data = [
... User('alice'),
... User('bob'),
... User('carol'),
... ]
>>>
>>>
>>> print(data)
[repr, repr, repr]
>>>
>>> data
[repr, repr, repr]
>>>
>>> str(data)
'[repr, repr, repr]'
>>>
>>> repr(data)
'[repr, repr, repr]'
11.2.5. Case Study
SECOND = 1
MINUTE = 60 * SECOND
HOUR = 60 * MINUTE
DAY = 24 * HOUR
WEEK = 7 * DAY
YEAR = 365.25 * DAY
MONTH = YEAR / 12
SOL = 24*HOUR + 39*MINUTE + 35.244*SECOND
class Mission:
def __init__(self, name, duration):
self.name = name
self.duration = duration
def __str__(self):
return f'{self.name}'
def __format__(self, unit):
duration = self.duration
match unit:
case 's' | 'sec' | 'seconds': duration /= SECOND
case 'm' | 'min' | 'minutes': duration /= MINUTE
case 'h' | 'hour' | 'hours': duration /= HOUR
case 'd' | 'day' | 'days': duration /= DAY
case 'w' | 'week' | 'weeks': duration /= WEEK
case 'mth'| 'month' | 'months': duration /= MONTH
case 'y' | 'year' | 'years': duration /= YEAR
case 'sol': duration /= SOL
return f'{duration:.1f} {unit}'
ares3 = Mission('Ares3', duration=543*SOL)
print(f'Mission Ares 3 duration was: {ares3:months}')
# Mission Ares 3 duration was: 18.3 months
11.2.6. Assignments
# %% About
# - Name: OOP Repr Overwrite
# - Difficulty: easy
# - Lines: 3
# - Minutes: 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Modify `User` to overwrite `__repr__()` method
# 2. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User` aby nadpisać metodę `__repr__()`
# 2. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> alice = User('Alice', 'Apricot')
# >>> alice
# User(firstname='Alice', lastname='Apricot')
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> alice = User('Alice', 'Apricot')
>>> alice
User(firstname='Alice', lastname='Apricot')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
User: type
__repr__: Callable[[object], str]
# %% Data
# %% Result
class User:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
# %% About
# - Name: OOP Repr Inheritance
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2
# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author
# %% English
# 1. Modify `User` to overwrite `__repr__()` method
# 2. Method should return proper class name on inheritance
# 3. Run doctests - all must succeed
# %% Polish
# 1. Zmodyfikuj klasę `User` aby nadpisać metodę `__repr__()`
# 2. Metoda powinna zwracać odpowiednią nazwę klasy przy dziedziczeniu
# 3. Uruchom doctesty - wszystkie muszą się powieść
# %% Example
# >>> alice = User('Alice', 'Apricot')
# >>> alice
# User(firstname='Alice', lastname='Apricot')
# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'
>>> alice = User('Alice', 'Apricot')
>>> alice
User(firstname='Alice', lastname='Apricot')
>>> bob = Admin('Bob', 'Blackthorn')
>>> bob
Admin(firstname='Bob', lastname='Blackthorn')
"""
# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`
# %% Imports
# %% Types
from typing import Callable
User: type
Admin: type
__repr__: Callable[[object], str]
# %% Data
# %% Result
class User:
def __init__(self, firstname, lastname):
self.firstname = firstname
self.lastname = lastname
def __repr__(self):
firstname = self.firstname
lastname = self.lastname
return f'User({firstname=}, {lastname=})'
class Admin(User):
pass