Python string.format() и Unicode - программирование
Подтвердить что ты не робот

Python string.format() и Unicode

У меня проблема с Python string.format() и передача ему строк Unicode. Это похоже на этот старый вопрос, за исключением того, что в моем случае тестовый код взрывается на принтере, а не на вызове logging.info(). Передача одного и того же строкового объекта Unicode на обработчик ведения журнала отлично работает.

Это не так хорошо относится к более раннему форматированию %, а также к string.format(). Просто чтобы убедиться, что это был строковый объект, проблема, а не плохое взаимодействие с моим терминалом, я попытался назначить форматированную строку переменной перед печатью.

def unicode_test():
    byte_string = '\xc3\xb4'
    unicode_string = unicode(byte_string, "utf-8")
    print "unicode object type: {}".format(type(unicode_string))
    output_string = "printed unicode object: {}".format(unicode_string)
    print output_string

if __name__ == '__main__':
    unicode_test()

Строковый объект, кажется, предполагает, что он получает ASCII.

% python -V
Python 2.7.2

% python ./unicodetest.py
unicode object type: <type 'unicode'>
Traceback (most recent call last):
  File "./unicodetest.py", line 10, in <module>
    unicode_test()
  File "./unicodetest.py", line 6, in unicode_test
    output_string = "printed unicode object: {}".format(unicode_string)
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf4' in position 0: ordinal not in range(128)

Попытка отличить output_string, поскольку Unicode не имеет никакого значения.

output_string = u "напечатанный unicode-объект: {}". format (unicode_string)

Я что-то упустил? Документация для строкового объекта кажется довольно ясной, что это должно работать, когда я пытаюсь ее использовать.

4b9b3361

Ответ 1

Нет, это не должно работать (можете ли вы привести часть документации, которая так говорит?), но она должна работать, если шаблон форматирования является unicode (или со старым форматированием, которое "продвигает" шаблон в Юникод, а не пытается для аргументов "demote" ).

>>> x = "\xc3\xb4".decode('utf-8')
>>> x
u'\xf4'
>>> x + 'a'
u'\xf4a'
>>> 'a' + x
u'a\xf4'
>>> 'a %s' % x
u'a \xf4'
>>> 'a {}'.format(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec 
  can't encode character u'\xf4' in position 0: ordinal not in range(128)
>>> u'a {}'.format(x)
u'a \xf4'
>>> print u"Foo bar {}".format(x)
Foo bar ô

Изменить: строка print может не работать для вас, если строка unicode не может быть закодирована с использованием вашей консоли. Например, на моей консоли Windows:

>>> import sys
>>> sys.stdout.encoding
'cp852'
>>> u'\xf4'.encode('cp852')
'\x93'

На консоли UNIX это может быть связано с вашими настройками локали. Он также потерпит неудачу, если вы перенаправите вывод (например, при использовании | в оболочке). Большинство из этих проблем были исправлены в Python 3.