python - string中文 - string to bytes




將字節轉換為字符串? (10)

我正在使用此代碼從外部程序獲取標準輸出:

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

通信()方法返回一個字節數組:

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

但是,我想用普通的Python字符串處理輸出。 這樣我可以像這樣打印它:

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

我認為這就是binascii.b2a_qp()方法的binascii.b2a_qp() ,但是當我嘗試它時,我又得到了相同的字節數組:

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

有誰知道如何將字節值轉換回字符串? 我的意思是,使用“電池”而不是手動進行。 我希望它能與Python 3一致。


你需要解碼bytes對象來產生一個字符串:

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

儘管@Aaron Maenpaa的答案正確,但最近一位用戶問道

有沒有更簡單的方法? 'fhand.read()。decode(“ASCII”)'[...]它太長了!

您可以使用

command_stdout.decode()

decode()有一個標準參數

codecs.decode(obj, encoding='utf-8', errors='strict')


在處理來自Windows系統的數據時(使用\r\n行尾),我的答案是

String = Bytes.decode("utf-8").replace("\r\n", "\n")

為什麼? 嘗試使用多行Input.txt:

Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8")
open("Output.txt", "w").write(String)

你所有的行結束都會加倍(到\r\r\n ),導致額外的空行。 Python的文本閱讀功能通常會標準化行尾,以便字符串僅使用\n 。 如果您從Windows系統收到二進制數據,Python沒有機會這樣做。 從而,

Bytes = open("Input.txt", "rb").read()
String = Bytes.decode("utf-8").replace("\r\n", "\n")
open("Output.txt", "w").write(String)

將復制您的原始文件。


如果你應該通過嘗試decode()來獲得以下內容:

AttributeError: 'str' object has no attribute 'decode'

您還可以在演員中直接指定編碼類型:

>>> my_byte_str
b'Hello World'

>>> str(my_byte_str, 'utf-8')
'Hello World'

將universal_newlines設置為True,即

command_stdout = Popen(['ls', '-l'], stdout=PIPE, universal_newlines=True).communicate()[0]

對於Python 3,這是一個更安全的Pythonic方法來從byte轉換為string

def byte_to_str(bytes_or_str):
    if isinstance(bytes_or_str, bytes): #check if its in bytes
        print(bytes_or_str.decode('utf-8'))
    else:
        print("Object not of byte type")

byte_to_str(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')

輸出:

total 0
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file1
-rw-rw-r-- 1 thomas thomas 0 Mar  3 07:03 file2

您需要解碼字節字符串並將其轉換為字符(unicode)字符串。

b'hello'.decode(encoding)

要么

str(b'hello', encoding)

我做了一個清理列表的函數

def cleanLists(self, lista):
    lista = [x.strip() for x in lista]
    lista = [x.replace('\n', '') for x in lista]
    lista = [x.replace('\b', '') for x in lista]
    lista = [x.encode('utf8') for x in lista]
    lista = [x.decode('utf8') for x in lista]

    return lista

我認為這種方式很簡單:

bytes = [112, 52, 52]
"".join(map(chr, bytes))
>> p44

要將字節序列解釋為文本,您必須知道相應的字符編碼:

unicode_text = bytestring.decode(character_encoding)

例:

>>> b'\xc2\xb5'.decode('utf-8')
'µ'

ls命令可能會產生不能被解釋為文本的輸出。 Unix上的文件名可以是除斜杠b'/'和零b'\0'外的任何字節序列:

>>> open(bytes(range(0x100)).translate(None, b'\0/'), 'w').close()

嘗試使用utf-8編碼解碼這種字節湯會引發UnicodeDecodeError

它可能會更糟。 如果您使用錯誤的不兼容編碼,解碼可能會失敗並產生mojibake

>>> '—'.encode('utf-8').decode('cp1252')
'—'

數據已損壞,但您的程序仍不知道發生了故障。

通常,使用什麼字符編碼並不嵌入字節序列本身。 您必須在帶外傳達此信息。 一些結果比其他結果更可能存在,因此chardet模塊存在,可以猜測字符編碼。 一個Python腳本可能在不同的地方使用多個字符編碼。

使用os.fsdecode()函數可以將ls輸出轉換為Python字符串,即使對於不可解碼的文件名也是如此 (它在Unix上使用sys.getfilesystemencoding()surrogateescape錯誤處理程序):

import os
import subprocess

output = os.fsdecode(subprocess.check_output('ls'))

要獲得原始字節,可以使用os.fsencode()

如果您傳遞了universal_newlines=True參數,則subprocess locale.getpreferredencoding(False)使用locale.getpreferredencoding(False)來解碼字節,例如,它可以是Windows上的cp1252

要實時解碼字節流,可以使用io.TextIOWrapper() : example 。

不同的命令可能會為其輸出使用不同的字符編碼,例如, dir內部命令( cmd )可能使用cp437。 要解碼它的輸出,你可以顯式地傳遞編碼(Python 3.6+):

output = subprocess.check_output('dir', shell=True, encoding='cp437')

文件名可能與os.listdir() (它使用Windows Unicode API)不同,例如, '\xb6'可以用'\x14'替代--Python的cp437編解碼器映射b'\x14'來控製字符U + 0014而不是U + 00B6(¶)。 要支持具有任意Unicode字符的文件名,請參閱將可能包含非ASCII字符 Unicode字符的poweshell輸出解碼為python字符串







python-3.x