Лучший тип вывода и практики кодирования для функций __REPR __ ()?

StackOverflow https://stackoverflow.com/questions/3627793

  •  26-09-2019
  •  | 
  •  

Вопрос

В последнее время у меня было много проблем с __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

Вот несколько дополнительных проблем, которые беспокоят меня, и я ищу решение, которое решает их:

  1. Печать к терминалу UTF-8 должна работать (у меня есть sys.stdout.encoding установлен в UTF-8, но было бы лучше, если бы другие дела тоже работали).
  2. Трубопровод Выход в файл (закодированный в UTF-8) должен работать (в этом случае, sys.stdout.encoding является None).
  3. Мой код для многих __repr__() Функции в настоящее время много return ….encode('utf-8'), и это тяжело. Есть ли что-нибудь надежное и легче?
  4. В некоторых случаях у меня даже есть уродливые звери, как 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))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top