Konwertuj bajty na ciąg znaków

I'm using this code to get standard output from an external program:

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

Metoda communicate() zwraca tablicę bajtów:

>>> 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'

Chciałbym jednak pracować z wyjściem jako normalnym ciągiem znaków Pythona. Tak, że mógłbym go wydrukować w ten sposób:

>>> 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

Myślałem, że do tego właśnie służy metoda binascii.b2a_qp(), ale kiedy ją wypróbowałem, otrzymałem ponownie tę samą tablicę bajtów:

>>> 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'

Jak przekonwertować wartość bajtów z powrotem na ciąg? Mam na myśli użycie "akumulatorów" zamiast robienia tego ręcznie. I chciałbym, żeby to było OK z Pythonem 3.

Rozwiązanie

Musisz zdekodować obiekt bajtów, aby uzyskać ciąg znaków:

>>> 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'
Komentarze (18)

Musisz zdekodować ciąg bajtów i przekształcić go w ciąg znaków (Unicode).

W Pythonie 2

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

lub

unicode('hello', encoding)

W Pythonie 3

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

lub

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

Myślę, że naprawdę tego chcesz:

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

Aaron's odpowiedź była poprawna, z wyjątkiem tego, że musisz wiedzieć, którego kodowania użyć. I wierzę, że Windows używa 'windows-1252'. Będzie to miało znaczenie tylko wtedy, gdy masz jakieś nietypowe (nieASCII) znaki w swojej zawartości, ale wtedy będzie to miało znaczenie.

Przy okazji, fakt, że ma to znaczenie, jest powodem, dla którego Python zaczął używać dwóch różnych typów dla danych binarnych i tekstowych: nie może magicznie konwertować między nimi, ponieważ nie zna kodowania, dopóki mu go nie podasz! Jedynym sposobem, w jaki TY byś wiedział, jest przeczytanie dokumentacji Windows (lub przeczytanie jej tutaj).

Komentarze (2)