Convertir bytes en una cadena

Estoy usando este código para obtener la salida estándar de un programa externo:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]

El método communicate() devuelve un array de bytes:

>>> command_stdout
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

Sin embargo, me gustaría trabajar con la salida como una cadena normal de Python. De manera que pudiera imprimirla así

>>> print(command_stdout)
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2

Pensé que para eso'es el método binascii.b2a_qp(), pero cuando lo probé, volví a obtener el mismo array de bytes:

>>> binascii.b2a_qp(command_stdout)
b'total 0\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1\n-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2\n'

¿Cómo puedo volver a convertir el valor de los bytes en cadena? Es decir, usando las "pilas" en lugar de hacerlo manualmente. Y me gustaría que estuviera bien con Python 3.

Solución

Es necesario decodificar el objeto bytes para producir una cadena:

>>> b"abcde"
b'abcde'

# utf-8 is used here because it is a very common encoding, but you
# need to use the encoding your data is actually in.
>>> b"abcde".decode("utf-8") 
'abcde'
Comentarios (18)

Es necesario decodificar la cadena de bytes y convertirla en una cadena de caracteres (Unicode).

En Python 2

encoding = 'utf-8'
'hello'.decode(encoding)

o

unicode('hello', encoding)

En Python 3

encoding = 'utf-8'
b'hello'.decode(encoding)

o

str(b'hello', encoding)
Comentarios (0)

Creo que realmente quieres esto:

>>> from subprocess import *
>>> command_stdout = Popen(['ls', '-l'], stdout=PIPE).communicate()[0]
>>> command_text = command_stdout.decode(encoding='windows-1252')

La respuesta de Aaron era correcta, excepto que necesitas saber qué codificación usar. Y creo que Windows utiliza 'windows-1252'. Sólo importará si tiene algunos caracteres inusuales (no ASCII) en su contenido, pero entonces hará una diferencia.

Por cierto, el hecho de que importe es la razón por la que Python pasó a usar dos tipos diferentes para los datos binarios y de texto: no puede convertir mágicamente entre ellos, ¡porque no sabe la codificación a menos que se lo digas! La única manera de saberlo es leyendo la documentación de Windows (o leyéndola aquí).

Comentarios (2)