__str__
и __repr__
, следует учитывать форматирование вложенных объектов. Используйте str()
или repr()
соответственно для представления вложенных объектов.
class Inner:
def __init__(self, value):
self.value = value
def __repr__(self):
return f"Inner({self.value!r})"
class Outer:
def __init__(self, inner):
self.inner = inner
def __str__(self):
return f"Outer object containing: {self.inner}"
def __repr__(self):
return f"Outer(inner={repr(self.inner)})"
Важно, чтобы __repr__
возвращал строку, которая, по возможности, позволит воссоздать объект. __str__
должен быть более читаемым для конечного пользователя. Используйте !r
в f-строках для вызова repr()
.
Переопределение методов __str__
и __repr__
для классов, использующих составные или вложенные объекты, требует особого внимания к читаемости и информативности результирующей строки.
Зачем это нужно?
__str__
: Предназначен для *неформального* представления объекта, ориентированного на пользователя. Часто используется для печати объекта (например, через print()
).__repr__
: Предназначен для *формального* представления объекта, полезного для отладки и воспроизведения. Идеально, чтобы результатом repr()
было выражение Python, которое создаст идентичный объект (если это возможно).Основные стратегии:
str()
и repr()
для вложенных объектов: Вызовите str(вложенный_объект)
в __str__
и repr(вложенный_объект)
в __repr__
, чтобы делегировать ответственность за форматирование вложенным объектам. Это обеспечит консистентность и повторное использование логики форматирования..format()
для создания читаемых строковых представлений.Пример:
class Address:
def __init__(self, street, city, zip_code):
self.street = street
self.city = city
self.zip_code = zip_code
def __str__(self):
return f"{self.street}, {self.city}, {self.zip_code}"
def __repr__(self):
return f"Address(street='{self.street}', city='{self.city}', zip_code='{self.zip_code}')"
class Person:
def __init__(self, name, age, address):
self.name = name
self.age = age
self.address = address
def __str__(self):
return f"Person: {self.name}, Age: {self.age}, Address: {self.address}"
def __repr__(self):
return f"Person(name='{self.name}', age={self.age}, address={repr(self.address)})"
address = Address("123 Main St", "Anytown", "12345")
person = Person("Alice", 30, address)
print(str(person)) # Output: Person: Alice, Age: 30, Address: 123 Main St, Anytown, 12345
print(repr(person)) # Output: Person(name='Alice', age=30, address=Address(street='123 Main St', city='Anytown', zip_code='12345'))
Разбор примера:
Address
методы __str__
и __repr__
возвращают строковое представление адреса.Person
метод __str__
использует str(self.address)
, чтобы получить строковое представление адреса.Person
метод __repr__
использует repr(self.address)
, чтобы получить формальное представление адреса. Важно использовать repr()
для вложенных объектов в __repr__
, чтобы представление было максимально информативным и позволяло воспроизвести объект.Рекомендации:
__repr__
. Это важный инструмент для отладки.__str__
, когда нужно более "дружелюбное" представление для пользователей.__str__
и __repr__
, чтобы убедиться, что они возвращают ожидаемые результаты.