Подтвердить что ты не робот

Как печатать кортежи строк unicode на языке оригинала (не u'foo)

У меня есть список кортежей объектов unicode:

>>> t = [('亀',), ('犬',)]

Распечатайте это, я получаю:

>>> print t
[('\xe4\xba\x80',), ('\xe7\x8a\xac',)]

который, я думаю, представляет собой список представления байтовых кодов utf-8 этих строк?

но то, что я хочу видеть распечатанным, удивляет:

[('亀',), ('犬',)]

но у меня возникает чрезмерная проблема с возвратом байт-кода в удобочитаемую форму.

4b9b3361

Ответ 1

но то, что я хочу видеть распечатанным, удивляет:

[('亀',), ('犬',)]

Что вы хотите увидеть на нем? Потому что если это консоль, это вовсе не гарантирует, что ваша консоль может отображать эти символы. Именно поэтому представление объектов Python 'repr() предназначено для безопасной опции \-escapes, которую вы всегда сможете увидеть на экране и легко ввести.

В качестве предпосылки вы должны использовать строки Unicode (u ''). И, как упоминалось Мэтью, если вы хотите, чтобы иметь возможность писать u '亀' непосредственно в исходном коде, вам нужно убедиться, что Python может читать кодировку файла. Для случайного использования символов, отличных от ASCII, лучше всего придерживаться экранированной версии u '\ u4e80', но когда у вас есть много восточноазиатского текста, который вы хотите читать, "# coding = utf-8" определенно путь.

print '[% s]'% ','.join([','.join('(% s,)'% ','.join(ti) для ti по t)])

Это будет печатать символы, развернутые кавычками. На самом деле вам нужно:

def reprunicode(u):
    return repr(u).decode('raw_unicode_escape')

print u'[%s]' % u', '.join([u'(%s,)' % reprunicode(ti[0]) for ti in t])

Это сработает, но если консоль не поддерживает Unicode (и это особенно неприятно для Windows), вы получите большой старый UnicodeError.

В любом случае это редко имеет значение, потому что функция repr() объекта, которую вы видите здесь, обычно не попадает в общедоступный пользовательский интерфейс приложения; это действительно только для кодера.

Однако вам будет приятно узнать, что Python 3.0 ведет себя так, как вы хотите:

  • plain '' без префикса u теперь являются строками Unicode
  • repr() показывает большинство символов Unicode дословно
  • Юникод в консоли Windows лучше поддерживается (вы все равно можете получить UnicodeError в Unix, если ваша среда не UTF-8)

Python 3.0 является немного новым и не очень хорошо поддерживается библиотеками, но он может наилучшим образом удовлетворить ваши потребности.

Ответ 2

Во-первых, есть небольшое недоразумение в вашем посте. Если вы определите такой список:

>>> t = [('亀',), ('犬',)]

... это не unicode, которые вы определяете, но str s. Если вы хотите иметь типы unicode, вы должны добавить u перед символом:

>>> t = [(u'亀',), (u'犬',)]

Но предположим, что вы действительно хотите str s, а не unicode s. Основная проблема заключается в том, что метод __str__ списка (или кортежа) практически равен его методу __repr__ (который возвращает строку, которая при оценке создаст точно тот же объект). Поскольку метод __repr__ должен быть независим от кодирования, строки представляются в самом безопасном режиме, то есть каждый символ вне диапазона ASCII представляется шестнадцатеричным символом (например, \xe4).

К сожалению, насколько мне известно, нет библиотечного метода для печати списка, который является локальным. Вы можете использовать функцию общего назначения следующим образом:

def collection_str(collection):
    if isinstance(collection, list):
        brackets = '[%s]'
        single_add = ''
    elif isinstance(collection, tuple):
        brackets = '(%s)'
        single_add =','
    else:
        return str(collection)
    items = ', '.join([collection_str(x) for x in collection])
    if len(collection) == 1:
        items += single_add
    return brackets % items

>>> print collection_str(t)
[('亀',), ('犬',)]

Обратите внимание, что это не будет работать для всех возможных коллекций (например, наборов и словарей), но его легко расширить, чтобы обработать их.

Ответ 3

Файлы исходного кода Python строго ASCII, поэтому вы должны использовать escape-последовательности \u, если вы не указали кодировку. См. PEP 0263.

#!/usr/bin/python
# coding=utf-8
t = [u'亀', u'犬']
print t

Когда вы передаете массив в print, Python преобразует объект в строку, используя Python правила для преобразования строк. Вывод таких преобразований рассчитан на eval(), поэтому вы видите последовательности \u. Вот хак, чтобы обойти это на основе решения bobince. Консоль должна принимать Unicode, иначе это вызовет исключение.

t = [(u'亀',), (u'犬',)]
print repr(t).decode('raw_unicode_escape')

Ответ 4

Try:

import codecs, sys
sys.stdout = codecs.getwriter('utf8')(sys.stdout)

Ответ 5

Итак, это похоже на то, что я хочу:

print '[%s]' % ', '.join([', '.join('(%s,)' % ', '.join(ti) for ti in t)])


>>> t = [('亀',), ('犬',)]
>>> print t
[('\xe4\xba\x80',), ('\xe7\x8a\xac',)]
>>> print '[%s]' % ', '.join([', '.join('(%s,)' % ', '.join(ti) for ti in t)])
[(亀,), (犬,)]

Конечно, есть лучший способ сделать это.

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

Ответ 6

Кажется, люди теряют то, чего хотят люди здесь. Когда я печатаю unicode из кортежа, я просто хочу избавиться от 'u' '[' '(' и quotes. То, что мы хотим, это функция, как показано ниже. После очистки Net это, по-видимому, самый чистый способ получить отображаемые атомом данные. Если данные не находятся в кортеже или списке, я не думаю, что эта проблема существует.

def Plain(self, U_String) :
          P_String = str(U_String)
          m=re.search("^\(\u?\'(.*)\'\,\)$", P_String)
          if (m) :  #Typical unicode
             P_String = m.group(1).decode("utf8")
          return P_String