Python: использование .format () в строке с экранированием Unicode


156

Я использую Python 2.6.5. Мой код требует использования знака «больше или равно». Здесь это идет:

>>> s = u'\u2265'
>>> print s
>>> 
>>> print "{0}".format(s)
Traceback (most recent call last):
     File "<input>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265'
  in position 0: ordinal not in range(128)`  

Почему я получаю эту ошибку? Есть ли правильный способ сделать это? Мне нужно использовать .format()функцию.

Ответы:


243

Просто сделайте вторую строку также строкой Unicode

>>> s = u'\u2265'
>>> print s

>>> print "{0}".format(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265' in position 0: ordinal not in range(128)
>>> print u"{0}".format(s)
≥
>>> 

40
@Kit: если вы хотите, чтобы все литералы были Unicode (как в Python 3), поместите их from __future__ import unicode_literalsв начало ваших исходных файлов.
Филипп

1
Да, это получится, если вы привыкли к форматированию%, так как этот "% s"% u "\ u2265" работает, но "{}". Format (u "\ u2265") выдаст исключение.
Хилидан

2
какая простая вещь ... какая ужасная головная боль у меня была, пока я не нашел этот кусочек просветления ...
Иосу С.


5

Немного больше информации о том , почему это происходит.

>>> s = u'\u2265'
>>> print s

работает, потому что printавтоматически использует системную кодировку для вашей среды, которая, вероятно, была установлена ​​в UTF-8. (Вы можете проверить, делая import sys; print sys.stdout.encoding)

>>> print "{0}".format(s)

терпит неудачу, потому что formatпытается соответствовать кодировке типа, к которому он вызывается (я не смог найти документацию по этому вопросу, но это поведение я заметил). Поскольку строковые литералы являются байтовыми строками, закодированными как ASCII в Python 2, он formatпытается кодировать sкак ASCII, что затем приводит к этому исключению. Заметим:

>>> s = u'\u2265'
>>> s.encode('ascii')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2265' in position 0: ordinal not in range(128)

Вот почему в основном эти подходы работают:

>>> s = u'\u2265'
>>> print u'{}'.format(s)

>>> print '{}'.format(s.encode('utf-8'))

Исходный набор символов определяется объявлением кодировки; это ASCII, если в исходном файле не указано объявление кодировки ( https://docs.python.org/2/reference/lexical_analysis.html#string-literals )


1
Да, и я обнаружил, что это очень помогает в понимании юникода в python и представления текста в компьютерных системах в целом: nedbatchelder.com/text/unipain.html
lps
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.