2017-01-04 169 views
0

我是Python 3的新手,似乎無法完全掌握unicode和字符編碼。當字節對象顯然只包含字符時,將Python 3字節對象轉換爲字符串

我正在處理另一個工具的輸出,它將html頁面的內容作爲字節對象返回。我們使用的其他工具需要此輸出爲字節類型,但是,我想將字節輸出轉換爲字符串,以便解析和比較其他字符串。對於我感興趣的情況,打印輸出字節對象只顯示字符並且不顯示\ x或\ u二進制文件。我對如何最好地做到這一點以及爲什麼創建所需輸出的方法實際上有效而感到困惑。

我已經在其他地方讀過.decode()應該在這個上下文中使用,這確實有效,但我不明白爲什麼我解碼已經是字符的對象。據我瞭解,解碼是爲二進制數,例如:

>>> b'\x41'.decode('utf-8') 
'A' 

在我的理解,我真正想要做的是告訴Python的是一個已經被標記爲一個字節類型對象的對象實際上是一個STR目的。只需在bytes對象上使用str()函數即可實現此目標,但會添加「b」前綴並在字符串周圍添加引號。

這裏有兩種解決方案我的工作:

>>> str(b'htmltext') 
"b'htmltext'" 

>>> b'htmltext'.decode('utf-8') 
'htmltext' 

從本質上講,這兩種方案似乎達到什麼我正在尋找,但解碼()似乎很明顯更清潔,並從什麼我讀過,推薦的方法。我想知道爲什麼解碼()的作品,鑑於此,顯然,我不會將二進制數字轉換爲字符。此外,除了輸出中沒有吸引力的「b」和引號外,是否還有其他原因,str()在這裏不是有效的解決方案?

+0

一旦你理解*爲什麼* Python3將字符串和二進制數據分爲兩種不同的類型,這將更容易回答。請參閱http://eli.thegreenplace.net/2012/01/30/the-bytesstr-dichotomy-in-python-3 – turbulencetoo

+1

* Everything *是二進制數據。 –

+0

認爲計算機中的每一件事物都有二進制表示是很自然的,但在Python中它不是那樣的 - 太糟糕了!特別是,字符串是沒有編碼的unicode對象,編碼是從unicode對象到字節對象的映射。這是查看字符串,字節對象及其關係的一種方式,但我看不到獲得的結果。 –

回答

4

請勿混淆bytes對象的開發人員友好型表示與其中包含的數據。你有兩種方式的二進制數據。

開發商表示,很容易讓你看到什麼是展示什麼,只是碰巧是一個有效的ASCII碼點爲ASCII字符,而不是\xhh轉義碼包含。以這種方式閱讀以ASCII編碼的文本更容易,而世界上的許多文本恰好是ASCII編碼的。

你有困難時,當數據不是然而ASCII範圍:

>>> 'Åæøéï'.encode('utf8') 
b'\xc3\x85\xc3\xa6\xc3\xb8\xc3\xa9\xc3\xaf' 

這是一個UTF-8字節序列編碼的文本與口音。以上可能有點做作,但大多數非英文文本將包含的一些非ASCII文本。即使是英文文本可以包含長劃線或花哨的報價,以及該b'...'字節版本是幾乎沒有的正確解碼文本版本的可讀性:

>>> '「Kragerø」 is a town in Norway – in the province of Vestfold'.encode('utf8') 
b'\xe2\x80\x9cKrager\xc3\xb8\xe2\x80\x9d is a town in Norway \xe2\x80\x93 in the province of Vestfold' 

注意,b'....'輸出使用repr() function結果在bytes對象;即調用object.__repr__() method,它具有爲您生成適合開發人員的字符串的顯式功能。 bytes對象上沒有專用object.__str__() method,但調用了__repr__方法,即使使用str()函數。將bytes轉換爲字符串的正確方法是解碼(使用正確的數據編解碼器)。

當然,當你有二進制數據代表別的東西,就像圖像數據一樣,然後把它保存爲bytes。沒有文字解碼。

+0

這個解釋非常有幫助。這填補了我在其他地方令我困擾的理解上的空白。謝謝! – QuintenG