Convertir bytes en cadenas en Python

     

    Introducci贸n

    En este art铆culo, veremos c贸mo convertir bytes en una cadena en Python. Al final de este art铆culo, tendr谩 una idea clara de qu茅 son estos tipos y c贸mo manejar eficazmente los datos us谩ndolos.

    Dependiendo de la versi贸n de Python que est茅 usando, esta tarea ser谩 diferente. Aunque Python 2 ha llegado al final de su vida 煤til, muchos proyectos todav铆a lo usan, por lo que incluiremos los enfoques de Python 2 y Python 3.

    Convertir bytes en cadenas en Python 3

    Desde Python 3, la antigua forma ASCII de hacer las cosas ten铆a que desaparecer y Python se convirti贸 completamente en Unicode.

    Esto significa que perdimos el tipo Unicode expl铆cito: u"string" – cada String es un u"string"!

    Para diferenciar estas cadenas de las cadenas de bytes antiguas, se nos presenta un nuevo especificador para ellas: el b"string".

    Esto se agreg贸 en Python 2.6, pero no sirvi贸 para otro prop贸sito real que el de prepararse para Python 3, ya que todas las cadenas eran cadenas de bytes en 2.6.

    Las cadenas de bytes en Python 3 se denominan oficialmente bytes, una secuencia inmutable de enteros en el rango 0 <= x <256. Otro bytes-objeto similar agregado en 2.6 es el bytearray – Similar a bytes, pero mutable.

    Convierta Bytes en String con decode ()

    Echemos un vistazo a c贸mo podemos convertir bytes en una cadena, usando la funci贸n incorporada decode() m茅todo para el bytes clase:

    >>> b = b"Lets grab a xf0x9fx8dx95!"
    # Let's check the type
    >>> type(b)
    <class 'bytes'>
    
    # Now, let's decode/convert them into a string
    >>> s = b.decode('UTF-8')
    >>> s
    "Let's grab a 馃崟!"
    

    Pasando el formato de codificaci贸n, hemos decodificado el bytes objeto en una String y lo imprim铆.

    Convierta bytes en cadenas con c贸decs

    Alternativamente, podemos usar el incorporado codecs m贸dulo tambi茅n para este prop贸sito:

    >>> import codecs
    >>> b = b'Lets grab a xf0x9fx8dx95!'
    
    >>> codecs.decode(b, 'UTF-8')
    "Let's grab a 馃崟!"
    

    Sin embargo, realmente no necesita pasar el par谩metro de codificaci贸n, se recomienda pasarlo:

    >>> codecs.decode(b)
    "Let's grab a 馃崟!"
    

    Convierta Bytes en String con str ()

    Finalmente, puede utilizar el str() funci贸n, que acepta varios valores y los convierte en cadenas:

    >>> b = b'Lets grab a xf0x9fx8dx95!'
    >>> str(b, 'UTF-8')
    "Let's grab a 馃崟!"
    

    Aseg煤rese de proporcionar el argumento de codificaci贸n a str() aunque, de lo contrario, podr铆a obtener algunos resultados inesperados:

    >>> str(b)
    b'Lets grab a xf0x9fx8dx95!'
    

    Esto nos lleva a las codificaciones una vez m谩s. Si especifica la codificaci贸n incorrecta, el mejor caso es que su programa se bloquee porque no puede decodificar los datos. Por ejemplo, si intentamos usar el str() funcionar con UTF-16, ser铆amos recibidos con:

    >>> str(b, 'UTF-16')
    '鏁屸澊u2073鐗ф墶鎰爑f020瓒熲啎'
    

    Esto es a煤n m谩s importante dado que a Python 3 le gusta asumir Unicode, por lo que si est谩 trabajando con archivos o fuentes de datos que usan una codificaci贸n oscura, aseg煤rese de prestar especial atenci贸n.

    Convertir bytes en cadenas en Python 2

    En Python 2, un paquete de bytes y una cadena son pr谩cticamente lo mismo: las cadenas son objetos que constan de caracteres de 1 byte, lo que significa que cada car谩cter puede almacenar 256 valores. Por eso a veces se les llama cadenas de bytes.

    Esto es genial cuando se trabaja con datos de bytes; simplemente los cargamos en una variable y estamos listos para imprimir:

    >>> s = "Hello world!"
    
    >>> s
    'Hello world!'
    
    >>> len(s)
    12
    

    Sin embargo, el uso de caracteres Unicode en cadenas de bytes cambia un poco este comportamiento:

    >>> s = "Let's grab a 馃崟!"
    
    >>> s
    'Lets grab a xf0x9fx8dx95!'
    # Where has the pizza gone to?
    
    >>> len(s)
    17
    # Shouldn't that be 15?
    

    Convertir bytes a Unicode (Python 2)

    Aqu铆, tendremos que usar Python 2 Unicode type, que se asume y se usa autom谩ticamente en Python 3. Esto almacena cadenas como una serie de puntos de c贸digo, en lugar de bytes.

    los xf0x9fx8dx95 representa bytes como n煤meros hexadecimales de dos d铆gitos, ya que Python no sabe c贸mo representarlos como caracteres ASCII:

    >>> u = u"Let's grab a 馃崟!"
    u"Let's grab a U0001f355!""
    
    >>> u
    "Let's grab a 馃崟!"
    # Yum.
    
    >>> len(u)
    15
    

    Como puede ver arriba, la cadena Unicode contiene U0001f355 – 隆un car谩cter de escape Unicode que nuestro terminal ahora sabe c贸mo imprimir como una porci贸n de pizza! Configurar esto fue tan f谩cil como usar el u especificador antes del valor de la cadena de bytes.

    Entonces, 驴c贸mo cambio entre los dos?

    Puede obtener la cadena Unicode decodificando su cadena de bytes. Esto se puede hacer construyendo un objeto Unicode, proporcionando la cadena de bytes y una cadena que contiene el nombre de codificaci贸n como argumentos o llamando .decode(encoding) en una cadena de bytes.

    Convertir bytes en cadenas usando decode () (Python 2)

    Tambi茅n puede utilizar el codecs.encode(s, encoding) desde el codecs m贸dulo.

    >>> s = "Let's grab a xf0x9fx8dx95!"
    >>> u = unicode(s, 'UTF-8')
    
    >>> u
    "Let's grab a 馃崟!"
    
    >>> s.decode('UTF-8')
    "Let's grab a 馃崟!"
    

    Convertir bytes en cadenas mediante c贸decs (Python 2)

    O, usando el codecs m贸dulo:

    import codecs
    
    >>> codecs.decode(s, 'UTF-8')
    "Let's grab a 馃崟!"
    

    Sea consciente de su codificaci贸n

    Una advertencia aqu铆: los bytes se pueden interpretar de manera diferente en diferentes codificaciones. Con alrededor 80 diferentes codificaciones disponibles listas para usar, 隆puede que no sea f谩cil saber si tienes la correcta!

    s="xf8xe7"
    
    # This one will let us know we used the wrong encoding
    
    >>> s.decode('UTF-8')
    UnicodeDecodeError: 'utf8' codec can't decode byte 0xf8 in position 0:
    invalid start byte
    
    # These two overlaps and this is a valid string in both
    
    >>> s.decode('latin1')
    酶莽
    
    s.decode('iso8859_5')
    褬褔
    

    El mensaje original era 酶莽 o 褬褔y ambas parecen ser conversiones v谩lidas.

    Conclusi贸n

    Como programadores, hay algunas cosas en las que debemos pensar constantemente y para las que debemos prepararnos activamente para evitar trampas. Esto es especialmente cierto en los niveles inferiores, a los que rara vez vamos cuando usamos un lenguaje de alto nivel como Python como nuestro controlador diario.

    Cosas como juegos de caracteres, codificaciones y binarios est谩n ah铆 para recordarnos que nuestro trabajo es c贸digo – codificar nuestros pensamientos en soluciones de trabajo. Afortunadamente, gran parte de este pensamiento se convierte en parte de nuestra rutina despu茅s de algunas rondas en el teclado.

    En este art铆culo, hemos repasado c贸mo convertir bytes a cadenas en Python.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *