open - Python UnicodeDecodeError-¿Estoy mal entendiendo la codificación?
u python (5)
... hay una razón por la que se llaman "codificaciones" ...
Un pequeño preámbulo: piense en unicode como la norma o el estado ideal. Unicode es solo una tabla de caracteres. №65 es la capital latina A. №937 es la capital griega omega. Solo eso.
Para que una computadora almacene y / o manipule Unicode, debe codificarlo en bytes. La codificación más simple de Unicode es UCS-4; cada personaje ocupa 4 bytes, y todos los ~ 1000000 caracteres están disponibles. Los 4 bytes contienen el número del carácter en las tablas Unicode como un entero de 4 bytes. Otra codificación muy útil es UTF-8, que puede codificar cualquier carácter Unicode con uno a cuatro bytes. Pero también hay algunas codificaciones limitadas, como "latin1", que incluyen una gama muy limitada de caracteres, principalmente utilizados por los países occidentales. Dichas codificaciones usan solo un byte por carácter.
Básicamente, Unicode se puede codificar con muchas codificaciones, y las cadenas codificadas se pueden decodificar a Unicode. El caso es que Unicode llegó bastante tarde, así que todos los que crecimos usando un juego de caracteres de 8 bits aprendimos demasiado tarde que todo este tiempo trabajamos con cadenas codificadas . La codificación podría ser ISO8859-1, o Windows CP437, o CP850, o, o, o, dependiendo de nuestro sistema predeterminado.
Entonces, cuando, en su código fuente, ingresa la cadena "agregar" Monitoreo "a la lista" (y creo que quería que la cadena "agregar" Monitoreo "a la lista", tenga en cuenta la segunda cita), en realidad está usando una cadena ya codificado de acuerdo con la página de códigos predeterminada de su sistema (por el byte / x93. Supongo que usa la página de códigos de Windows 1252, "Western"). Si desea obtener Unicode de eso, necesita decodificar la cadena desde la codificación "cp1252".
Entonces, lo que pretendías hacer era:
"add /x93Monitoring/x94 to list".decode("cp1252", "ignore")
Es lamentable que Python 2.x incluya un método .encode
para cadenas también; esta es una función de conveniencia para codificaciones "especiales", como las "zip" o "rot13" o "base64", que no tienen nada que ver con Unicode.
De todos modos, todo lo que debe recordar para sus conversiones Unicode de ida y vuelta es:
- una cadena Unicode se codifica en una cadena de Python 2.x (en realidad, una secuencia de bytes)
- una cadena de Python 2.x se decodifica en una cadena Unicode
En ambos casos, debe especificar la codificación que se utilizará.
No estoy muy claro, tengo sueño, pero espero haber ayudado.
PD Una nota al margen humorística: los mayas no tenían Unicode; los antiguos romanos, los antiguos griegos, los antiguos egipcios no lo hicieron también. Todos tenían sus propias "codificaciones", y tenían poco o ningún respeto por otras culturas. Todas estas civilizaciones se convirtieron en polvo. Piénselo personas! Haga que sus aplicaciones sean compatibles con Unicode, por el bien de la humanidad. :)
PS2 No estropee el mensaje anterior diciendo "Pero los chinos ...". Sin embargo, si te sientes inclinado u obligado a hacerlo, demora pensando que el BMP Unicode está poblado principalmente por ideogramas chinos, ergo Chinese es la base de Unicode. Puedo seguir inventando mentiras escandalosas, siempre y cuando las personas desarrollen aplicaciones conscientes de Unicode. ¡Aclamaciones!
¿Alguna idea de por qué esto no está funcionando? Realmente pensé que ''ignorar'' haría lo correcto.
>>> ''add /x93Monitoring/x93 to list ''.encode(''latin-1'',''ignore'')
Traceback (most recent call last):
File "<interactive input>", line 1, in ?
UnicodeDecodeError: ''ascii'' codec can''t decode byte 0x93 in position 4: ordinal not in range(128)
Esto parece funcionar:
''add /x93Monitoring/x93 to list ''.decode(''latin-1'').encode(''latin-1'')
¿Algún problema con eso? Me pregunto cuándo entrará en juego ''ignorar'', ''reemplazar'' y otro tipo de manejo de errores de codificación.
Experimentando el mismo problema; sin embargo, tiene problemas para entender cómo incluir apropiadamente la sintaxis de codificación sin generar más errores o un error de sintaxis no válida.
genesis_block = {
''hash'': hash_function({
''block_number'': 0,
''parent_hash'': None,
''transaction_count'': 1,
''transaction'': [{''Tom'': 10}]
}),
''contents'': {
''block_number'': 0,
''parent_hash'': None,
''transaction_count'': 1,
''transaction'': [{''Tom'': 10}]
},
}
block_chain = [genesis_block]
chain_state = {''Tom'': 10}
También escribí un blog extenso sobre este tema:
encode está disponible para cadenas unicode, pero la cadena que tienes allí no parece unicode (prueba con u''add / x93Monitoring / x93 para listar '')
>>> u''add /x93Monitoring/x93 to list ''.encode(''latin-1'',''ignore'')
''add /x93Monitoring/x93 to list ''