На этом шаге мы рассмотрим отличия по использованию этого метода в предыдущей версии Python.
В Python 3 имеется один тип данных на все случаи жизни для представления текста: str. Он содержит символы Юникода и может представлять большинство систем письменности в мире.
В Python 2.x для строковых данных используется другая модель данных.
См. документацию Python 2 "Модель данных": https://docs.python.org/2/reference/datamodel.html.
Для представления текста служат два типа: str, который ограничен набором символов ASCII, и unicode, который эквивалентен типу str Python 3.
Вследствие этой разницы в Python 2 существует еще один дандер-метод в составе методов управления преобразованием строк: __unicode__. В Python 2 __str__ возвращает байты, тогда как __unicode__ возвращает символы.
По своим замыслу и целям метод __unicode__ является более новым и предпочтительным методом управления преобразованием строк. Кроме того, имеется сопровождающая его встроенная функция unicode(). Она вызывает соответствующий дандер-метод подобно тому, как работают функции str() и repr().
Чем дальше, тем лучше. Но все станет намного причудливее, когда вы посмотрите на правила вызова методов __str__ и __unicode__ в Python 2.
Инструкция print() и функция str() вызывают метод __str__. Встроенная в Python 2 функция unicode() вызывает метод __unicode__, если он существует; в противном случае отыгрывает назад к методу __str__ и декодирует результат в системную кодировку текста.
По сравнению с Python 3 эти особые случаи несколько усложняют правила преобразования текста. Но есть способ все снова упростить в практическом плане. Юникод является предпочтительным и перспективным способом работы с текстом в программах Python.
Поэтому в Python 2.x в целом рекомендуется размещать весь свой код форматирования строк внутри метода __unicode__, а затем создавать реализацию заглушки __str__, которая возвращает представление в виде Юникода в кодировке UTF-8:
def __str__(self): return unicode(self).encode('utf-8')
Заглушка __str__ будет одинаковой для большинства классов, ее вы просто можете копипастить повсюду, где это необходимо (либо разместить ее в базовом классе, где это имеет смысл). Тогда весь ваш код преобразования строк, который предназначен для использования не разработчиками, будет лежать в методе __unicode__.
Приведем законченный пример для Python 2.x:
class Car(object): def __init__(self, color, mileage): self.color = color self.mileage = mileage def __repr__(self): return '{}({!r}, {!r})'.format(self.__class__.__name__, self.color, self.mileage) def __unicode__(self): return u'{self.color} автомобиль'.format(self=self) def __str__(self): return unicode(self).encode('utf-8')
На следующем шаге мы подитожим изученный материал.