Как напечатать кортежи строк Unicode на языке оригинала (не в форме u'foo) - PullRequest
11 голосов
/ 07 марта 2009

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

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

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

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

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

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

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

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

Ответы [ 6 ]

7 голосов
/ 07 марта 2009

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

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

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

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

print '[% s]'% ',' .join ([',' .join ('(% s,)'% ',' .join (ti) для ti in 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 ведет себя именно так, как вы хотите:

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

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

3 голосов
/ 07 марта 2009

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

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

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

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

Но давайте предположим, что вы действительно хотите str с, а не unicode с. Основная проблема заключается в том, что __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)
[('亀',), ('犬',)]

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

2 голосов
/ 07 марта 2009

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

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

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

t = [(u'亀',), (u'犬',)]
print repr(t).decode('raw_unicode_escape')
0 голосов
/ 12 апреля 2014

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

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  
0 голосов
/ 07 марта 2009

Похоже, это делает то, что я хочу:

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)])
[(亀,), (犬,)]

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

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

0 голосов
/ 07 марта 2009

Попробуйте:

import codecs, sys
sys.stdout = codecs.getwriter('utf8')(sys.stdout)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...