¿Cómo convierto una variable de cadena de bytes de Python 3 en una cadena regular?

116

He leído en un archivo adjunto de correo electrónico XML con

bytes_string=part.get_payload(decode=False)

La carga útil viene como una cadena de bytes, como sugiere el nombre de mi variable.

Estoy tratando de usar el enfoque recomendado de Python 3 para convertir esta cadena en una cadena utilizable que pueda manipular.

El ejemplo muestra:

str(b'abc','utf-8')

¿Cómo puedo aplicar el bargumento de palabra clave (bytes) a mi variable bytes_stringy usar el enfoque recomendado?

La forma en que lo intenté no funciona:

str(bbytes_string, 'utf-8')
DjangoTango
fuente

Respuestas:

210

Lo tenías casi bien en la última línea. Usted quiere

str(bytes_string, 'utf-8')

porque el tipo de bytes_stringes bytes, el mismo que el tipo de b'abc'.

Toby Speight
fuente
6
str(bytes_string, 'utf-8', 'ignore')Los errores se pueden ignorar pasando el tercer parámetro.
Shubhamoy
2
Parece que debería ser un comentario a la respuesta de pylang (que aborda el manejo de entradas no válidas). Si (cree que) no hay nada de malo en bytes_stringello, ¿por qué querría ignorar los errores?
Toby Speight
3
Me estoy haciendo siguiente error con su enfoque: UnicodeDecodeError: 'utf-8' codec can't decode byte 0xbf in position 0: invalid start bytepara la siguiente cadena de bytes b'\xbf\x8cd\xba\x7f\xe0\xf0\xb8t\xfe.TaFJ\xad\x100\x07p\xa0\x1f90\xb7P\x8eP\x90\x06)0'@TobySpeight
Alper
Bueno @alper, esa no es una cadena UTF-8 válida, entonces, ¿qué esperabas?
Toby Speight
Gracias por la solución
Ajay Kumar
49

Llame decode()a una bytesinstancia para obtener el texto que codifica.

str = bytes.decode()
uname01
fuente
5
UnicodeDecodeError: el códec 'utf-8' no puede decodificar el byte 0xf6 en la posición 230: byte de inicio no válido
Juha Untinen
3
@JuhaUntinen, tu codificación probablemente no sea utf-8.
tommy.carstensen
4
¿Cómo filtrar (omitir) charachers que no sean UTF8 de la matriz?
Dr. Failov
9

ACTUALIZADO:

NO TENER NINGUNA by citas al principio y al final

Cómo convertir bytescomo se ve en cadenas, incluso en situaciones extrañas.

Como su código puede tener caracteres irreconocibles para 'utf-8'codificar, es mejor usar solo str sin ningún parámetro adicional:

some_bad_bytes = b'\x02-\xdfI#)'
text = str( some_bad_bytes )[2:-1]

print(text)
Output: \x02-\xdfI

si agrega un 'utf-8'parámetro, a estos bytes específicos, debería recibir un error.

Como dice el estándar PYTHON 3, ahora textestaría en utf-8 sin ninguna preocupación.

Seyfi
fuente
el resultado es "b '\\ x02 - \\ xdfI #)'" que probablemente no sea lo que quiere
Glen Thompson
@GlenThompson es solo un ejemplo de condiciones no deseadas que pueden suceder. Utilizo este texto específico intencionalmente. Si quiere decir que el texto tiene una entrada b, entonces actualicé la respuesta
Seyfi
así que muchas gracias, estoy buscando una forma de eliminar la b '' de una cadena que tiene un carácter ansi sin codificar y perder los caracteres, soy nuevo en Python y no sé si puedo reducir una matriz desde el principio y comenzando a usar índices: O
Diego Fernando Murillo Valenci
@DiegoFernandoMurilloValenci, de tu bienvenida. Me alegro de poder ayudar.
Seyfi
6

¿Cómo filtrar (omitir) charachers que no sean UTF8 de la matriz?

Para abordar este comentario en la publicación de @ uname01 y el OP, ignore los errores:

Código

>>> b'\x80abc'.decode("utf-8", errors="ignore")
'abc'

Detalles

De los documentos , aquí hay más ejemplos que usan el mismo errorsparámetro:

>>> b'\x80abc'.decode("utf-8", "replace")
'\ufffdabc'
>>> b'\x80abc'.decode("utf-8", "backslashreplace")
'\\x80abc'
>>> b'\x80abc'.decode("utf-8", "strict")  
Traceback (most recent call last):
    ...
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0:
  invalid start byte

El argumento de errores especifica la respuesta cuando la cadena de entrada no se puede convertir de acuerdo con las reglas de codificación. Los valores legales para este argumento son 'strict'(generar una UnicodeDecodeErrorexcepción), 'replace'(usar U+FFFD, REPLACEMENT CHARACTER) o 'ignore'(simplemente dejar el carácter fuera del resultado Unicode).

pylang
fuente