2010-07-20 34 views
9

Quería url codificar una cadena de pitón y obtuve excepciones con cadenas hebreas. No pude solucionarlo y comencé a hacer algo de programación orientada a adivinar. Finalmente, al hacer mystr = mystr.encode("utf8") antes de enviarlo al codificador de URL se guardó el día.Python: ¿qué arregla "...". Encode ("utf8")?

¿Alguien puede explicar lo que pasó? ¿Qué hace .encode ("utf8")? Mi cadena original era de todos modos una cadena unicode (es decir, precedida por una u).

+9

No es una respuesta directa, pero vale la pena leer este texto: [El mínimo absoluto de cada desarrollador de software Absolutamente, definitivamente debe saber acerca de Unicode y conjuntos de caracteres (Sin excusas!)] (Http: //www.joelonsoftware. com/articles/Unicode.html) por Joel Spolsky – balpha

+8

Programación orientada a la conjetura. Ahora que es un paradigma popular :) – Amnon

+0

en mi experiencia aprendiendo sobre los conceptos básicos (como lo estás haciendo aquí) es más eficaz. – Amnon

Respuesta

9

Su cadena original era un objeto Unicode que contiene puntos de código Unicode sin formato, después de codificarlo como UTF-8 es una cadena de bytes normal que contiene UTF-8 datos codificados.

El codificador de URL parece esperar una cadena de bytes, por lo que puede codificar URL de un byte tras otro y no tiene que ocuparse de los puntos de código Unicode. Cuando le das un objeto Unicode, intenta convertirlo a una cadena de bytes usando alguna codificación predeterminada, probablemente ASCII. Para los caracteres hebreos que no se pueden representar como ASCII, esto dará lugar a errores.

1

"...". Encode ("utf-8") transforma la representación en memoria de la cadena en una cadena codificada en UTF-8.

url encoder probablemente esperaba una cadena de bytes, es decir, una representación de cadena donde cada carácter se representa con un solo byte.

0

Devuelve una versión con codificación UTF-8 de la cadena Unicode, mystr. Es importante darse cuenta de que UTF-8 es simplemente 1 forma de codificar Unicode. Python puede trabajar con muchas otras codificaciones (por ejemplo, mystr.encode ("utf32") o incluso mystr.encode ("ascii")).

0

El link que publicó balpha lo explica todo. En resumen:

El hecho de que la cadena fue prefijado con "u" simplemente significa que está compuesto por caracteres Unicode (o puntos de código). UTF-8 es una codificación de esta cadena en una secuencia de bytes.

13

Mi cadena original era de todos modos una cadena Unicode (es decir, el prefijo de una u)

... cual es el problema. No era una "cadena", como tal, sino un "objeto Unicode". Contiene una secuencia de puntos de código Unicode. Estos puntos de código deben, por supuesto, tener alguna representación interna de la que Python tenga conocimiento, pero sea lo que sea, se abstrae y se muestran como esas entidades \uXXXX cuando print repr(my_u_str).

Para obtener una secuencia de bytes que otro programa pueda comprender, debe tomar esa secuencia de puntos de código Unicode y codificarla. Debe decidir sobre la codificación, porque hay mucho para elegir. UTF8 y UTF16 son opciones comunes. ASCII podría serlo también, si cabe. u"abc".encode('ascii') funciona bien.

Haz my_u_str = u"\u2119ython" y luego type(my_u_str) y type(my_u_str.encode('utf8')) para ver la diferencia de tipos: El primero es <type 'unicode'> y el segundo es <type 'str'>. (Debajo de Python 2.5 y 2.6, de todos modos).

Las cosas son diferentes en Python 3, pero como rara vez lo uso, estaría hablando por mi cuenta si traté de decir algo autoritario al respecto.

+0

+1 Gran explicación. –

+0

[Este] (https://tools.ietf.org/html/rfc3986) parece implicar utf-8 para cualquier cosa que no sea ASCII, y si es de w3schools, sabemos que no tiene autoridad. w3fools.com – stommepoes

4

¿Qué hace .encode ("utf8")?

Depende de la versión de Python que está utilizando:

  • En Python 3.x, convierte un objeto str (codificada en UTF-16 o UTF-32) en un objeto bytes que contiene la representación UTF-8 de la cadena.
  • En Python 2.x, convierte un objeto unicode en un objeto str codificado en UTF-8. Pero str también tiene un método encode, y escribir '...'.encode('UTF-8') equivale a escribir '...'.decode('ascii').encode('UTF-8').

Como ha mencionado el prefijo "u", debe estar utilizando 2.x. Si no necesita ninguna biblioteca 2.x solamente, le recomendaría cambiar a 3.x, que tiene una clara distinción clara entre texto y datos binarios.

Dive into Python 3 tiene una buena explicación del problema.

¿Alguien puede explicar lo que pasó?

Ayudaría si nos dijera cuál fue el mensaje de error.

La función urllib.quote espera un objeto str. También funciona con unicode objetos que contienen solo caracteres ASCII, pero no cuando contienen letras hebreas.

En 3.x Python, urllib.parse.quote acepta tanto str (= Python 2.x unicode) y bytes objetos. Las cadenas se codifican automáticamente en UTF-8.

Cuestiones relacionadas