Шаг 61.
Python: тонкости программирования. Классы и ООП. Преобразование строк (использование __repr__). Почему каждый класс нуждается в __repr__

    На этом шаге мы попытаемся обосновать необходимость наличия в классе этого метода.

    Если опустить метод __str__, то Python в поисках __str__ отыграет назад к результату __repr__. По этой причине мы рекомендуем добавлять в свои классы всегда, по крайней мере, метод __repr__. Это обеспечит полезный результат преобразования строк почти во всех случаях при минимуме работы по его реализации.

    Ниже показано, как можно быстро и эффективно добавить в свои классы элементарную поддержку преобразования строк. Для нашего класса Car мы могли бы начать с приведенного ниже метода :

def __repr__(self):
    return f'Car({self.color!r}, {self.mileage!r})'

    Обратите внимание на то, что мы используем флаг преобразования !r, тем самым гарантируя, что в выводимом строковом значении вместо str(self.color) и str(self.mileage) будут использованы repr(self. color) и repr(self.mileage).

    Это работает безупречно, но оборотной стороной является то, что мы повторили имя класса в форматной строке. Для того чтобы избежать этого повторения, здесь можно применить трюк с использованием атрибута __calss__.__name__ объекта. Данный атрибут всегда будет зеркально отображать имя класса в виде строки.

    Преимущество состоит в том, что вам не придется модифицировать реализацию метода __repr__, когда имя класса изменится. Это позволяет беспрепятственно придерживаться принципа DRY, то есть "не повторяйся":

def __repr__(self):
    return (f'{self.__class__.__name__}('
              f'{self.color!r}, {self.mileage!r})')

    Оборотной стороной этой реализации является то, что форматная строка довольно длинная и громоздкая. Но при условии выверенного форматирования вы сможете сохранить свой исходный код аккуратным и соответствующим правилам PEP8.

    Во время инспектирования объекта или непосредственного вызова функции repr() с объектом при наличии приведенной выше реализации метода __repr__ мы получаем полезный результат:

>>> repr(my_car)
'Car(red, 37281)'

    Печать объекта или вызов функции str() с этим объектом возвращают то же самое строковое значение, потому что заданная по умолчанию реализация __str__ просто вызывает метод __repr__:

>>> print(my_car)
'Car(red, 37281)'
>>> str(my_car)
'Car(red, 37281)'

    Убеждены, что этот подход обеспечивает наибольшую эффективность и скромный объем работы по его реализации. Более того, этот подход опирается на типовой шаблон в стиле формы для печенья, который можно применять, не особо задумываясь. По этой причине можно всегда стремлитьсяь добавлять в свои классы элементарную реализацию метода __repr__.

    Ниже показан законченный пример для Python 3 с дополнительной реализацией метода __str__:

>>> class Car:
	def __init__(self, color, mileage):
		self.color = color
		self.mileage = mileage
	def __repr__(self):
		return (f'{self.__class__.__name__}('
			f'{self.color!r}, {self.mileage!r})')
	def __str__(self):
		return f'{self.color} автомобиль'

    На следующем шаге мы рассмотрим отличия Python 2.x.




Предыдущий шаг Содержание Следующий шаг