Python: Usando .format () em uma cadeia de caracteres com escape Unicode

156

Estou usando o Python 2.6.5. Meu código requer o uso do sinal "mais que ou igual a". Aqui vai:

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

Por que eu recebo esse erro? Existe uma maneira certa de fazer isso? Eu preciso usar a .format()função

Kit
fonte

Respostas:

243

Apenas faça da segunda string também uma string 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)
≥
>>> 
Cientista maluco
fonte
40
@Kit: Se você deseja que todos os literais sejam Unicode (como no Python 3), coloque from __future__ import unicode_literalsno início dos arquivos de origem.
Philipp
1
Sim, isso indica se você está acostumado a% de formatação, pois este "% s"% u "\ u2265" funciona, mas o formato "{}". (U "\ u2265") gera uma exceção.
Hylidan
2
o que é uma coisa simples .. o que uma terrível dor de cabeça que eu tenho até que encontrei este pedaço de iluminação ..
Iosu S.
70

unicodes precisam de unicodestrings de formato.

>>> print u'{0}'.format(s)
Ignacio Vazquez-Abrams
fonte
5

Um pouco mais de informação sobre por que isso acontece.

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

funciona porque printusa automaticamente a codificação do sistema para o seu ambiente, que provavelmente foi definida como UTF-8. (Você pode verificar fazendo import sys; print sys.stdout.encoding)

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

falha porque formattenta corresponder à codificação do tipo em que é chamado (não consegui encontrar documentação sobre isso, mas esse é o comportamento que notei). Como literais de strings são strings de bytes codificados como ASCII no python 2, formattenta codificar scomo ASCII, o que resulta nessa exceção. Observar:

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

Então é basicamente por isso que essas abordagens funcionam:

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

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

O conjunto de caracteres de origem é definido pela declaração de codificação; é ASCII se nenhuma declaração de codificação for fornecida no arquivo de origem ( https://docs.python.org/2/reference/lexical_analysis.html#string-literals )

lps
fonte
1
Ah, e eu encontrei este para ser de grande ajuda para unicode compreensão em python, e representação de texto em sistemas de computador em geral: nedbatchelder.com/text/unipain.html
lps