Cómo convertir los bytes en cadenas en Python 2 y Python 3

  1. Convertir Bytes a Cadena en Python 2.x
  2. Convertir Bytes a Cadena en Python 3.x
  3. Comparación de rendimiento y conclusión de los diferentes métodos de conversión de bytes a cadenas de texto

Este artículo del tutorial introducirá cómo convertir bytes a cadena en Python 2.x y Python 3.x.

Convertir Bytes a Cadena en Python 2.x

bytes en Python 2.7 es idéntico a str, por lo tanto la variable iniciada como bytes es la cadena intrínsecamente.

Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> A = b'cd'
>>> A
'cd'
>>> type(A)
<type 'str'>

Convertir Bytes a Cadena en Python 3.x

bytes es un nuevo tipo de datos introducido en Python 3.

Python 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> A = b'cd'
>>> A
b'cd'
>>> type(A)
<class 'bytes'>
>>> 

El tipo de datos de los elementos en los bytes es int.

>>> A = b'cd'
>>> A[0]
99
>>> type(A[0])
<class 'int'>

Convertir Bytes a Cadena usando decode en Python 3.x

El método .decode de bytes podría convertir los bytes a cadena con el método encoding dado. Está bien en la mayoría de los casos si dejas el método encoding como utf-8 por defecto, pero no siempre es seguro porque los bytes podrían ser codificados con otro método de codificación en lugar de utf-8.

>>> b'\x50\x51'.decode()
'PQ'
>>> b'\x50\x51'.decode('utf-8')
'PQ'
>>> b'\x50\x51'.decode(encoding = 'utf-8')
'PQ'

Las tres formas de decodificar los bytes como se muestra arriba son idénticas porque se utiliza utf-8 como método de codificación.

Podría dar lugar a errores cuando se utiliza utf-8 pero los bytes no se codifican con él.

>>> b'\x50\x51\xffed'.decode('utf-8')
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    b'\x50\x51\xffed'.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid start byte

Obtenemos el UnicodeDecodeError que dice que utf-8 no es el codec correcto.

Tenemos dos enfoques para resolver este problema de codificación.

backslashreplace, ignore o replace como parámetros para los errors

Decode tiene el otro parámetro además de encoding - errors. Define el comportamiento cuando ocurre un error. El valor por defecto de errors es strict, lo que significa que se produce un error si el error ocurre en el proceso de decodificación.

Error tiene otras opciones como ignore, replace u otros nombres registrados de codecs.register_error, backlashreplace por ejemplo.

Ignora los errores de decodificación erróneos y crea la cadena de salida como puede.

replace reemplaza los caracteres correspondientes con los caracteres definidos en el método de encoding tal y como se indica, y backslashreplace reemplaza los caracteres que no pudieron ser decodificados con el mismo contenido que en los bytes originales.

>>> b'\x50\x51\xffed'.decode('utf-8', 'backslashreplace')
'PQ\\xffed'
>>> b'\x50\x51\xffed'.decode('utf-8', 'ignore')
'PQed'
>>> b'\x50\x51\xffed'.decode('utf-8', 'replace')
'PQ�ed'

Se puede utilizar la codificación de MS-DOS cp437 si se desconoce la codificación de los datos de los bytes.

>>> b'\x50\x51\xffed'.decode('cp437')
'PQ\xa0ed'

chr para convertir los bytes a cadena en Python 3.x

chr(i, /) devuelve una cadena Unicode de un carácter con ordinal. Podría convertir el elemento de bytes en una string pero no los bytes completos.

Podríamos usar la comprensión de listas o map para obtener la cadena de bytes convertida mientras empleamos chr para un elemento individual.

>>> A =  b'\x50\x51\x52\x53'
>>> "".join([chr(_) for _ in A])
'PQRS'
>>> "".join(map(chr, A))
'PQRS'

Comparación de rendimiento y conclusión de los diferentes métodos de conversión de bytes a cadenas de texto

Usamos timeit para comparar el rendimiento del método introducido en este tutorial - decode y chr.

>>> import timeit
>>> timeit.timeit('b"\x50\x51\x52\x53".decode()', number=1000000)
0.1356779
>>> timeit.timeit('"".join(map(chr, b"\x50\x51\x52\x53"))', number=1000000)
0.8295201999999975
>>> timeit.timeit('"".join([chr(_) for _ in b"\x50\x51\x52\x53"])', number=1000000)
0.9530071000000362

Puede ver que el rendimiento del tiempo mostrado anteriormente, decode() es mucho más rápido y chr() es relativamente ineficiente porque necesita reconstruir la cadena a partir del carácter de una sola cadena.

Recomendamos usar decode en la aplicación de rendimiento crítico.

Artículo relacionado - Python Bytes

  • Convertir Byte a Hex en Python
  • Cómo convertir una cadena en bytes en Python
  • Artículo relacionado - Python Encoding-Decoding

  • Convertir Byte a Hex en Python
  • Cómo convertir una cadena en bytes en Python
  • Artículo relacionado - Python String

  • Eliminar números de cadena en Python
  • Cómo convertir una lista en cadena en Python