Tengo una cadena Unicode recuperada de un servicio web usando el requests
module, que contiene los bytes de un documento binario (PCL, como ocurre). Uno de estos bytes tiene el valor 248, y el intento de base64 codifican conduce al error siguiente:base64 codificación cadenas unicode en python 2.7
In [68]: base64.b64encode(response_dict['content']+'\n')
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
C:\...\<ipython-input-68-8c1f1913eb52> in <module>()
----> 1 base64.b64encode(response_dict['content']+'\n')
C:\Python27\Lib\base64.pyc in b64encode(s, altchars)
51 """
52 # Strip off the trailing newline
---> 53 encoded = binascii.b2a_base64(s)[:-1]
54 if altchars is not None:
55 return _translate(encoded, {'+': altchars[0], '/': altchars[1]})
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 272: ordinal not in range(128)
In [69]: response_dict['content'].encode('base64')
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
C:\...\<ipython-input-69-7fd349f35f04> in <module>()
----> 1 response_dict['content'].encode('base64')
C:\...\base64_codec.pyc in base64_encode(input, errors)
22 """
23 assert errors == 'strict'
---> 24 output = base64.encodestring(input)
25 return (output, len(input))
26
C:\Python27\Lib\base64.pyc in encodestring(s)
313 for i in range(0, len(s), MAXBINSIZE):
314 chunk = s[i : i + MAXBINSIZE]
--> 315 pieces.append(binascii.b2a_base64(chunk))
316 return "".join(pieces)
317
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf8' in position 44: ordinal not in range(128)
Me parece un poco sorprendente, porque 248 está dentro de la gama de un byte sin signo (y puede mantenerse en una cadena de bytes), pero mi verdadera pregunta es: ¿cuál es la mejor o la forma correcta de codificar esta cadena?
Mi solución alternativa actual es la siguiente:
In [74]: byte_string = ''.join(map(compose(chr, ord), response_dict['content']))
In [75]: byte_string[272]
Out[75]: '\xf8'
Esto parece funcionar correctamente, y el byte_string
resultante es capaz de ser codificada en base64, pero parece que no debe haber una mejor manera. ¿Esta ahí?
248 puede estar dentro del rango de un byte sin signo, pero no está en el rango de ASCII estandarizado [0-127]. – Cameron
@Cameron: un verdadero y buen punto, pero todavía no explica el problema, ya que el mismo valor exacto, cuando se mantiene en una cadena de bytes no da como resultado ese error. – Marcin
Ver mi respuesta :-) Lo que has hecho es tomar los puntos de código de la cadena 'unicode' y tratarlos como bytes. Esto es ... sospechoso en el mejor de los casos, ya que no hay garantía de que los puntos de código estén dentro del rango 0-255. Lo que es aún peor es que nadie más sabrá cómo interpretar la cadena de bytes más adelante, ya que está en una codificación personalizada e indefinida. – Cameron