Разница 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 
  • Проблемы с Unicode при использовании io.StringIO для издевательства файла
  • Проблемы с кодировкой Python и BeautifulSoup
  • Текст в PNG для App Engine (Python)
  • Удаление символов, отличных от ASCII, из строки с использованием python / django
  • Как использовать символы Unicode с PIL?
  • Преобразование в Emoji
  • Коды символов юникода Python?
  • сообщение python-requests с именами файлов в unicode
  • noob-запросы по методам unicode и str в Python
  •  
    Interesting Posts for Van-Lav

    Пакет python-pip yum предоставляет pip-python вместо pip

    Отключить разбивку на страницы в Django tastypie?

    Как построить вычислительно интенсивный веб-сервис?

    Google App Engine appcfg.py data_upload Ошибка аутентификации

    Pandas, конвертировать столбец из юникодов в столбец списка строк

    Как я могу обойти ошибку модуля kivy: ImportError: Ошибка загрузки DLL: указанного модуля не удалось найти?

    Список процессов в Linux через Python

    Как распечатать на принтере ОС по умолчанию на Python 3 (кросс-платформу)?

    Относительный импорт в Python 3 не работает

    Python: относительный импорт означает, что вы не можете самостоятельно выполнить подпакет?

    Pylint: отключить определенные предупреждения для определенной папки.

    Заполните значения формы на веб-странице с помощью скрипта Python (а не тестирования)

    Matplotlib, альтернативы savefig () для повышения производительности при сохранении объекта CString?

    Внедрение AMQP C ++

    ubuntu 11.04 lxml import etree проблема для пользовательского python

    Python - лучший язык программирования в мире.