Разница Python между print obj и print obj .__ str __ ()

Мне было дано понять, что вызов print obj вызовет obj.__str__() который, в свою очередь, вернет строку для печати на консоль. Теперь я столкнулся с проблемой с Unicode, где я не мог напечатать никаких символов, отличных от ascii. Я получил типичный материал «ascii вне диапазона».

При экспериментировании работали:

 print obj.__str__() print obj.__repr__() 

Поскольку обе функции выполняют точно то же самое ( __str__() просто возвращает self.__repr__() ). Что не получилось:

 print obj 

Проблема возникла только при использовании символа из диапазона ascii. Окончательное решение заключалось в следующем в __str__() :

 return self.__repr__().encode(sys.stdout.encoding) 

Теперь он работает для всех частей. Теперь мой вопрос: где разница? Почему он работает сейчас? Я получаю, если ничего не работает, почему это работает сейчас. Но почему работает только верхняя часть, а не нижняя.

ОС – Windows 7 x64 с командной строкой по умолчанию Windows. Также сообщается, что кодирование является cp850 . Это более общий вопрос для понимания python. Моя проблема уже решена, но я не на 100% счастлив, главным образом потому, что теперь вызов str(obj) даст строку, которая не закодирована так, как я этого хотел.

 # -*- coding: utf-8 -*- class Sample(object): def __init__(self): self.name = u"üé" def __repr__(self): return self.name def __str__(self): return self.name obj = Sample() print obj.__str__(), obj.__repr__(), obj 

Удалите последний obj и он работает. Держите его, и он падает с

 UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) 

2 Solutions collect form web for “Разница Python между print obj и print obj .__ str __ ()”

Я предполагаю, что печать для объекта obj предназначена для печати следующим образом:

  1. Проверяет, является ли obj unicode . Если это так, кодирует его в sys.stdout.encoding и печатает.
  2. Проверяет, является ли obj str . Если это так, распечатайте его напрямую.
  3. Если obj – что-то еще, вызывает str(obj) и печатает это.

Шаг 1. Почему print obj.__str__() работает в вашем случае.

Теперь, что делает str(obj) :

  1. Вызов obj.__str__() .
  2. Если результатом является str , верните его
  3. Если результат является unicode , он кодирует его "ascii" и возвращает это
  4. В противном случае что-то в основном бесполезно.

Вызов obj.__str__() напрямую пропускает шаги 2-3, поэтому вы не получаете отказ в кодировке.

Проблема не связана с тем, как работает print , это вызвано тем, как работает str() . str() игнорирует sys.stdout.encoding . Поскольку он не знает, что вы хотите сделать с полученной строкой, используемая по умолчанию кодировка может считаться произвольной; ascii – это хороший или плохой выбор, как любой.

Чтобы предотвратить эту ошибку, убедитесь, что вы вернули str из __str__() как указано в документации. Шаблон, который вы могли бы использовать для Python 2.x, может быть:

 class Foo(): def __unicode__(self): return u'whatever' def __str__(self): return unicode(self).encode(sys.stdout.encoding) 

(Если вы уверены, что вам не нужно представление str() для чего угодно, кроме печати на консоли.)

Во-первых, если вы смотрите онлайн-документацию , __str__ и __repr__ имеют разные цели и должны создавать разные результаты. Поэтому вызов __repr__ из __str__ не является лучшим решением.

Во-вторых, print будет вызывать __str__ и не будет ожидать получения символов, отличных от ascii, потому что, ну, print не может угадать, как преобразовать символ non-ascii.

Наконец, в последних версиях Python 2.x __unicode__ является предпочтительным методом создания строкового представления для объекта. В Python str и unicode есть интересное объяснение.

Итак, чтобы ответить на этот вопрос, вы можете сделать что-то вроде:

 class Sample(object): def __init__(self): self.name = u"\xfc\xe9" # No need to implement __repr__. Let Python create the object repr for you def __str__(self): return unicode(self).encode('utf-8') def __unicode__(self): return self.name 
  • UnicodeEncodeError: кодек ascii не может кодировать символы
  • Как преобразовать строку в utf-8 в Python
  • Как сделать Django slugify правильной работой с строками Unicode?
  • Python Unicode, имеет номер юникода в обычной строке, хочет печатать unicode
  • django: gettext и принуждение к unicode
  • python - Проблема сохранения символа Unicode для MySQL с Django
  • Как удалить u '(unicode) из словаря в Python?
  • Unicode и `decode ()` в Python
  • Strange `UnicodeEncodeError`, используя` os.path.exists`
  • Что означает «u» в списке?
  • как писать код unicode csv в Python 2.7
  • Python - лучший язык программирования в мире.