NOTA: esto fue escrito para Python 2.x No estoy seguro si es aplicable a 3.x.
Su uso de str
para datos binarios sin procesar en la memoria es correcto.
[Si está usando Python 2.6+, es incluso mejor usar bytes
que en 2.6+ es solo un alias de str
pero expresa su intención mejor, y le ayudará si un día transfiere el código a Python 3.]
Como otros señalan, escribir datos binarios a través de un códec es extraño. Un códec de escritura toma unicode y emite bytes en el archivo. Intentas hacerlo al revés, de ahí nuestra confusión sobre tus intenciones ...
[Y tu diagnóstico del error parece correcto: dado que el códec espera unicode, Python está decodificando tu str en unicode con la codificación predeterminada del sistema , que se ahoga.]
¿Qué desea ver en el archivo de salida?
Si el archivo debe contener los datos binarios como está:
Entonces no hay que enviarlo a través de un códec; debe escribirlo directamente en el archivo.Un códec codifica todo y solo puede emitir codificaciones válidas de Unicode (en su caso, UTF-8 válido). No hay entrada que pueda darle para emitir secuencias de bytes arbitrarias !
- Si necesita una mezcla de datos binarios UTF-8 y primas, que debe abrir el archivo directamente, y se entremezclan escribe de
some_data
con some_text.encode('utf8')
...
Nota sin embargo, que mezclar UTF-8 con datos arbitrarios crudos es muy mal diseño, porque tales archivos son muy inconvenientes para tratar con! Las herramientas que entienden Unicode se ahogarán en los datos binarios de , dejándote con una manera no conveniente de ver (ni hablar de modificar) el archivo.
Si desea usar una representación de bytes arbitrarias en Unicode:
Pass data.encode('base64')
al codec. Base64 produce solo ascii limpio (letras, números y un pequeño signo de puntuación) para que se pueda incrustar claramente en cualquier elemento, claramente se ve a las personas como datos binarios, y es razonablemente compacto (ligeramente más del 33% de sobrecarga).
P.S. Puede notar que data.encode('base64')
es extraño.
.encode()
se supone que tomar Unicode pero yo estoy dando una cadena ?! Python tiene varios pseudo-codecs que convierten str-> str como 'base64' y 'zlib'.
.encode()
siempre devuelve un str pero lo alimentarás en un códec esperando unicode ?! En este caso, solo contendrá limpio ascii, por lo que no importa. Puede escribir explícitamente data.encode('base64').encode('utf8')
si le hace sentir mejor.
Si necesita un mapeado 1: 1 de bytes arbitrarias a unicode:
Pass data.decode('latin1')
al codec. latin1
mapas bytes 0-255 para caracteres unicode 0-255, que es un poco elegante.
El códec será, por supuesto, codificar sus caracteres - 128-255 son codificado como 2 o 3 bytes en UTF-8 (sorprendentemente, el promedio sobrecarga es 50%, más de base64!). Esto mata bastante la "elegancia" de tener un mapeo 1: 1.
Tenga en cuenta también que los caracteres Unicode 0-255 incluyen personajes desagradables invisible/control (salto de línea, salto de página, guión de separación, etc.) haciendo que sus datos binarios molesto para ver en editores de texto.
Teniendo en cuenta estos inconvenientes, No recomiendo latin1 a menos que entienda exactamente por qué lo quiere.
Solo lo menciono como la otra codificación "natural" que surge en .
Dice que tiene datos sin formato de una vez, ¿cómo está generando esos datos en primer lugar? Supongo que tienes una fuente Unicode en alguna parte, pero no tengo claro si estás escribiendo unicode "en bruto" en str, o si lo estás leyendo desde un archivo (como objeto) o ... (¡Publicar una cadena de ejemplo que demuestre este error sería útil!) –