Улучшение представления объектов с помощью __repr__
В Python объекты могут быть представлены в виде строк двумя разными способами. Эти представления служат разным целям и полезны в различных сценариях.
Первый тип - это строковое представление. Оно создается функцией str(), которая автоматически вызывается при использовании функции print(). Строковое представление предназначено для удобного чтения человеком. Оно представляет объект в формате, который легко понять и интерпретировать.
Второй тип - это кодовое представление. Оно генерируется функцией repr(). Кодовое представление показывает код, который нужно написать, чтобы воссоздать объект. Оно больше ориентировано на точное и однозначное представление объекта в коде.
Давайте рассмотрим конкретный пример с использованием встроенного класса date в Python. Это поможет вам увидеть разницу между строковым и кодовым представлениями на практике.
>>> from datetime import date
>>> d = date(2008, 7, 5)
>>> print(d) ## Uses str()
2008-07-05
>>> d ## Uses repr()
datetime.date(2008, 7, 5)
В этом примере, когда мы используем print(d), Python вызывает функцию str() для объекта date d, и мы получаем человекочитаемую дату в формате ГГГГ-ММ-ДД. Когда мы просто вводим d в интерактивной оболочке, Python вызывает функцию repr(), и мы видим код, необходимый для воссоздания объекта date.
Вы можете явно получить строку repr() различными способами. Вот несколько примеров:
>>> print('The date is', repr(d))
The date is datetime.date(2008, 7, 5)
>>> print(f'The date is {d!r}')
The date is datetime.date(2008, 7, 5)
>>> print('The date is %r' % d)
The date is datetime.date(2008, 7, 5)
Теперь давайте применим этот концепт к нашему классу Stock. Мы будем улучшать класс, реализовав метод __repr__. Этот специальный метод вызывается Python, когда ему нужен кодовое представление объекта.
Для этого откройте файл stock.py в вашем редакторе. Затем добавьте метод __repr__ в класс Stock. Метод __repr__ должен возвращать строку, которая показывает код, необходимый для воссоздания объекта Stock.
def __repr__(self):
return f"Stock('{self.name}', {self.shares}, {self.price})"
После добавления метода __repr__ ваш полный класс Stock должен выглядеть следующим образом:
class Stock:
def __init__(self, name, shares, price):
self.name = name
self.shares = shares
self.price = price
def cost(self):
return self.shares * self.price
def sell(self, shares):
self.shares -= shares
def __repr__(self):
return f"Stock('{self.name}', {self.shares}, {self.price})"
Теперь давайте протестируем наш модифицированный класс Stock. Откройте интерактивную оболочку Python, выполнив следующую команду в терминале:
python3
После открытия интерактивной оболочки попробуйте следующие команды:
>>> import stock
>>> goog = stock.Stock('GOOG', 100, 490.10)
>>> goog
Stock('GOOG', 100, 490.1)
Вы также можете увидеть, как метод __repr__ работает с портфелем акций. Вот пример:
>>> import reader
>>> portfolio = reader.read_csv_as_instances('portfolio.csv', stock.Stock)
>>> portfolio
[Stock('AA', 100, 32.2), Stock('IBM', 50, 91.1), Stock('CAT', 150, 83.44), Stock('MSFT', 200, 51.23), Stock('GE', 95, 40.37), Stock('MSFT', 50, 65.1), Stock('IBM', 100, 70.44)]
Как вы можете видеть, метод __repr__ сделал наши объекты Stock гораздо более информативными при отображении в интерактивной оболочке или отладчике. Теперь он показывает код, необходимый для воссоздания каждого объекта, что очень полезно для отладки и понимания состояния объектов.
После завершения тестирования вы можете выйти из интерпретатора Python, выполнив следующую команду:
>>> exit()