Python: uso de .format () en una cadena con escape Unicode

156

Estoy usando Python 2.6.5. Mi código requiere el uso del signo "más que o igual a". Aquí va:

>>> 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 qué recibo este error? ¿Hay una manera correcta de hacer esto? Necesito usar la .format()función.

Equipo
fuente

Respuestas:

243

Simplemente haga que la segunda cadena también sea una cadena 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)
≥
>>> 
Científico loco
fuente
40
@ Kit: si desea que todos los literales sean Unicode (como en Python 3), colóquelos from __future__ import unicode_literalsal comienzo de sus archivos fuente.
Philipp
1
Sí, esto lo conseguirá si está acostumbrado a formatear% ya que este "% s"% u "\ u2265" funciona, pero "{}". Format (u "\ u2265") arrojará una excepción.
Hylidan
2
qué cosa tan simple ... qué dolor de cabeza terrible tuve hasta que encontré este poco de iluminación ..
Iosu S.
70

unicodes necesitan unicodecadenas de formato.

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

Un poco más de información sobre por qué sucede eso.

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

funciona porque printusa automáticamente la codificación del sistema para su entorno, que probablemente se configuró en UTF-8. (Puede verificar haciendo import sys; print sys.stdout.encoding)

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

falla porque formatintenta hacer coincidir la codificación del tipo al que se llama (no pude encontrar documentación sobre esto, pero este es el comportamiento que he notado). Dado que los literales de cadena son cadenas de bytes codificadas como ASCII en python 2, formatintenta codificar scomo ASCII, lo que resulta en esa excepción. 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)

Entonces, esa es básicamente la razón por la que funcionan estos enfoques:

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

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

El conjunto de caracteres de origen se define mediante la declaración de codificación; es ASCII si no se proporciona una declaración de codificación en el archivo fuente ( https://docs.python.org/2/reference/lexical_analysis.html#string-literals )

lps
fuente
1
Ah, y descubrí que esto es de gran ayuda para comprender Unicode en Python y la representación de texto en sistemas informáticos en general: nedbatchelder.com/text/unipain.html
lps