[Python] Me hago un lio tremendo con encode y decode

Iniciado por $francisco, Septiembre 18, 2015, 06:13:33 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Septiembre 18, 2015, 06:13:33 PM Ultima modificación: Septiembre 21, 2015, 09:54:15 AM por Expermicid
Qué tal a todos!

Como bien digo no logro entender para qué sirve realmente esto y agradecería que me lo explicaran, a poder ser con algún ejemplo porque no logro entender para qué codificarlo y descodificarlo.

Si es cierto que lo he visto en multitud de web como lo utilizan e incluso lo he utilizado con pyqt y en alguna otra ocasión pero... no lo logro comprender, por si os sirve de ayuda dejo un trozo de código que hice para que veáis mas o menos por que mi confusión.

Código: python
str(QtCore.QString(video+'.mp4').toUtf8()).decode('utf-8')


De esta manera logro que pueda imprimir correctamente el nombre de un vídeo que lleva acentuación pero no sé el por qué de tanta descodificacion para lograr esto.


Diciembre 10, 2015, 07:01:03 PM #1 Ultima modificación: Diciembre 10, 2015, 07:05:25 PM por WhiZ
Hola @No tienes permitido ver los links. Registrarse o Entrar a mi cuenta! Revolviendo un poco la sección de "Dudas y pedidos generales" me encontré con este post tuyo (no lo había visto en su momento jeje).

Sinceramente, desconocía esta técnica y, por ende, su intención. Luego de un pequeño análisis, llegué a la conclusión de que se utiliza, no para imprimir en pantalla caracteres especiales - ya que eso se puede hacer de forma directa con el método toUtf8 - sino para convertir el dato de QByteArray a unicode.

Para que se entienda bien, te explico paso por paso. Vamos a suponer que tenemos el siguiente código:
Código: python
# -*- coding:utf-8 -*-
from PyQt4 import QtCore

texto = QtCore.QString(u'niño')

print texto


Como vemos, la variable texto almacena un dato de tipo No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Si queremos imprimir su contenido en pantalla - que es lo que hacemos en el código anterior -, lo único que veremos será el siguiente error:
Código: text
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf1' in position 2: ordinal not in range(128)


Para entender mejor qué significa este UnicodeEncodeError, podemos recurrir a No tienes permitido ver los links. Registrarse o Entrar a mi cuenta y a No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

La pregunta que nos hacemos a continuación es: ¿cómo lo resolvemos?. Para esto, QString nos aporta un método llamado No tienes permitido ver los links. Registrarse o Entrar a mi cuenta que nos facilita la tarea. El mismo nos crea un dato de tipo No tienes permitido ver los links. Registrarse o Entrar a mi cuenta que, tal y como se dice en la documentación, no es más que una representación en UTF-8 del contenido de QString. Con este nuevo objeto, ya somos capaces de imprimir los caracteres especiales sin problema.

El código que presento a continuación, es capaz de manejar el error e imprimir el texto en pantalla:
Código: python
# -*- coding:utf-8 -*-
from PyQt4 import QtCore

texto = QtCore.QString(u'niño')

try:
    print texto
except UnicodeDecodeError:
    print texto.toUtf8()


Bien. Con esto queda resuelto el tema de imprimir datos de tipo QString con caracteres especiales. Sin embargo, todavía no respondo a tu pregunta: ¿por qué transformar un dato de tipo QString a QByteArray, luego a str y, por último, a unicode? xD

Lo primero que tengo que pensar es que la intención no es, simplemente, imprimir un QString con caracteres especiales. Como acabamos de decir, no hace falta más que llamar al método toUtf8 para hacerlo. Entonces, lo siguiente que se me viene a la mente es que la idea es convertir el dato de QString a unicode. Suponiendo que ése es el objetivo, hagamos un análisis de la situación y averiguemos el porqué de esta técnica:
Código: python
# -*- coding:utf-8 -*-
from PyQt4 import QtCore

texto = QtCore.QString(u'niño')
u_texto = str(texto.toUtf8()).decode('utf-8')  # convertimos a unicode

print "Tipo:", type(u_texto)
print "Texto:", u_texto


Al ejecutar el script, obtenemos la siguiente salida:
Código: text
Tipo: <type 'unicode'>
Texto: niño


Ahora voy a probar algo más simple:
Código: python
# -*- coding:utf-8 -*-
from PyQt4 import QtCore

texto = QtCore.QString(u'niño')
u_texto = unicode(texto)  # convertimos a unicode

print "Tipo:", type(u_texto)
print "Texto:", u_texto


Veamos qué pasa al ejecutarlo:
Código: text
Tipo: <type 'unicode'>
Texto: niño


Conclusión: como dije al principio, aparentemente, la técnica no se utiliza para imprimir un dato de tipo QString que contenga caracteres especiales sino para convertirlo al tipo unicode. No obstante, existe una forma más sencilla que consiste en llamar a la función unicode y pasarle como argumento el dato tipo QString. Con esta información en nuestras manos, sólo se me ocurren dos cosas: es, simplemente, una alternativa más compleja para hacer la conversión ó, posiblemente, una técnica que, además de la hacer la conversión, nos otorga algunos beneficios que desconozco.

Bueno, esto es todo lo que se me ocurre luego de analizar todo por un rato. Si alguien tiene algo más que aportar, adelante ;)

Saludos!
WhiZ


Muchas gracias whiz por tu respuesta, seguro que me sirve, a veces esto de codificar y descodificar me da dolores de cabeza en algunas ocasiones y a veces dificil de comprender y esa linea de código no tiene nada en especial o veneficio simplemente logré hacerla aleatoriamente para que pyqt me aceptara la variable para poder ver un video y solamente así me la aceptaba aunque no probré de la segunda forma que pusiste, repito thank por tu respuesta  ;D