Python: использование .format () в строке с экранированием Unicode - PullRequest
149 голосов
/ 13 июля 2010

Я использую 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().

Ответы [ 3 ]

230 голосов
/ 13 июля 2010

Просто сделайте вторую строку также строкой 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)
≥
>>> 
69 голосов
/ 13 июля 2010

unicode s нужно unicode строки формата.

>>> print u'{0}'.format(s)
≥
1 голос
/ 18 марта 2019

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

>>> 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)

...