Лучший тип вывода и практики кодирования для функций __REPR __ ()?
Вопрос
В последнее время у меня было много проблем с __repr__()
, format()
, и кодировки. Должен ли вывод __repr__()
быть закодированным или быть строкой Unicode? Есть ли лучший кодировщик для результата __repr__()
в питоне? То, что я хочу выводить, имеет символы без ASCII.
Я использую Python 2.x и хочу написать код, который может быть легко адаптирован к Python 3. Таким образом, программа использует
# -*- coding: utf-8 -*-
from __future__ import unicode_literals, print_function # The 'Hello' literal represents a Unicode object
Вот несколько дополнительных проблем, которые беспокоят меня, и я ищу решение, которое решает их:
- Печать к терминалу UTF-8 должна работать (у меня есть
sys.stdout.encoding
установлен вUTF-8
, но было бы лучше, если бы другие дела тоже работали). - Трубопровод Выход в файл (закодированный в UTF-8) должен работать (в этом случае,
sys.stdout.encoding
являетсяNone
). - Мой код для многих
__repr__()
Функции в настоящее время многоreturn ….encode('utf-8')
, и это тяжело. Есть ли что-нибудь надежное и легче? - В некоторых случаях у меня даже есть уродливые звери, как
return ('<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')
, т. Е. Представление объектов декодировано, помещают в строку форматирования, а затем повторно закодированы. Я хотел бы избежать таких запутанных преобразований.
Что бы вы порекомендовали сделать, чтобы написать просто __repr__()
Функции, которые ведут себя хорошо относительно этих вопросов кодирования?
Решение
В Python2, __repr__
(и __str__
) должен вернуть строковый объект, а не объект Unicode. В Python3 ситуация обращается, __repr__
и __str__
Необходимо вернуть объекты Unicode, не байт (Née String) объекты:
class Foo(object):
def __repr__(self):
return u'\N{WHITE SMILING FACE}'
class Bar(object):
def __repr__(self):
return u'\N{WHITE SMILING FACE}'.encode('utf8')
repr(Bar())
# ☺
repr(Foo())
# UnicodeEncodeError: 'ascii' codec can't encode character u'\u263a' in position 0: ordinal not in range(128)
В Python2 у вас на самом деле нет выбора. Вы должны выбрать кодировку для возврата значения __repr__
.
Кстати, вы прочитали Printfails wiki.? Это может не напрямую ответить на ваши другие вопросы, но я нашел его полезным в освещении, почему возникают определенные ошибки.
Когда используешь from __future__ import unicode_literals
,
'<{}>'.format(repr(x).decode('utf-8'))).encode('utf-8')
может быть просто написано как
str('<{}>').format(repr(x))
предположить str
кодирует utf-8
в вашей системе.
Без from __future__ import unicode_literals
, Выражение может быть написано как:
'<{}>'.format(repr(x))
Другие советы
Я думаю, что декоратор может управлять __repr__
несовместимость в правом пути. Вот что я использую:
from __future__ import unicode_literals, print_function
import sys
def force_encoded_string_output(func):
if sys.version_info.major < 3:
def _func(*args, **kwargs):
return func(*args, **kwargs).encode(sys.stdout.encoding or 'utf-8')
return _func
else:
return func
class MyDummyClass(object):
@force_encoded_string_output
def __repr__(self):
return 'My Dummy Class! \N{WHITE SMILING FACE}'
Я использую функцию, как следующее:
def stdout_encode(u, default='UTF8'):
if sys.stdout.encoding:
return u.encode(sys.stdout.encoding)
return u.encode(default)
Тогда мой __repr__
Функции выглядят так:
def __repr__(self):
return stdout_encode(u'<MyClass {0} {1}>'.format(self.abcd, self.efgh))