2009-01-15 96 views
152

我從來不確定我是否理解str/unicode解碼和編碼之間的區別。編碼/解碼有什麼區別?

我知道str().decode()是用於當你有一個字節的字符串,你知道有一個特定的字符編碼,給定的編碼名稱它將返回一個Unicode字符串。

我知道unicode().encode()根據給定的編碼名稱將unicode字符轉換爲一個字節的字符串。

但我不明白str().encode()unicode().decode()是什麼。任何人都可以解釋,並可能還糾正我上面錯誤的任何其他內容?

編輯:

幾個答案給什麼.encode確實在一根繩子上的信息,但沒有人知道什麼.decode確實對Unicode。

+0

我認爲[本頁]的第二個答案(http://stackoverflow.com/questions/10288016/usage-of-unicode-and-encode-functions-in-python)足夠清晰和簡潔。 – Ben 2016-12-01 11:24:22

回答

92

unicode字符串的decode方法根本沒有任何應用程序(除非你有一些非t由於某種原因,在一個unicode字符串中擴展數據 - 參見下文)。我想這主要是出於歷史原因。在Python 3中,它完全消失了。

unicode().decode()將使用默認(ascii)編解碼器執行隱含的編碼s。驗證是這樣的:

>>> s = u'ö' 
>>> s.decode() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0: 
ordinal not in range(128) 

>>> s.encode('ascii') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode character u'\xf6' in position 0: 
ordinal not in range(128) 

錯誤消息是完全一樣的。

對於str().encode()它周圍的其他方法 - 它企圖的s一個隱含解碼默認編碼:

>>> s = 'ö' 
>>> s.decode('utf-8') 
u'\xf6' 
>>> s.encode() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: 
ordinal not in range(128) 

像這樣來使用,str().encode()也是多餘的。

但是則存在是非常有用的後一種方法的另一種應用:有encodings具有無關的字符集,因此可以以有意義的方式被施加到8位字符串:

>>> s.encode('zip') 
'x\x9c;\xbc\r\x00\x02>\x01z' 

你說的對:這兩個應用程序的「編碼」的模糊用法是...... awkard。再次,在Python 3中使用單獨的bytestring類型,這不再是問題。

5

有幾種編碼可用於從str到str或從unicode到unicode的解碼/編碼。例如base64,hex或甚至rot13。它們在codecs module中列出。

編輯:

上Unicode字符串解碼消息可以撤消對應的編碼操作:

In [1]: u'0a'.decode('hex') 
Out[1]: '\n' 

返回的類型的STR代替的unicode這是在我的意見不幸。但是,如果你沒有在str和unicode之間進行正確的en/decode,反正看起來像是一團糟。

+1

-1:解碼方法未應用於unicode對象。相反,在解碼操作開始之前,unicode對象被編碼爲'ascii'字符串。爲了證明這個斷言,試試u'ã'.decode('hex') - 這會產生UnicodeEncodeError – nosklo 2009-01-16 11:17:30

+2

@nosklo:你說得對。我真正的意思是,unicode對象有一個decode()方法,以便您可以將非字符編碼的編解碼器應用於它們。這整個非字符編碼業務使得這個接口在Python中很亂。<3 – 2009-01-16 19:43:32

12

mybytestring.encode(somecodec)是有意義的的somecodec這些值:

  • 的base64
  • BZ2
  • ZLIB
  • 六角
  • quopri
  • ROT13
  • string_escape
  • uu

我不確定什麼解碼已解碼的Unicode文本是有益的。嘗試使用任何編碼似乎總是嘗試先用系統的默認編碼進行編碼。

+0

這真是太棒了!謝謝。 – dotancohen 2013-12-29 08:42:02

58

將Unicode字符串表示爲一個字節串被稱爲編碼。使用u'...'.encode(encoding)

例子:

 
    >>> u'æøå'.encode('utf8') 
    '\xc3\x83\xc2\xa6\xc3\x83\xc2\xb8\xc3\x83\xc2\xa5' 
    >>> u'æøå'.encode('latin1') 
    '\xc3\xa6\xc3\xb8\xc3\xa5' 
    >>> u'æøå'.encode('ascii') 
    UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-5: 
    ordinal not in range(128) 

您通常編碼unicode字符串,當您需要使用它的IO,例如將其傳送通過網絡,或將其保存到磁盤文件。

將一串字節轉換爲一個Unicode字符串被稱爲解碼。使用unicode('...', encoding)或'...'。解碼(編碼)。

例子:

 
    >>> u'æøå' 
    u'\xc3\xa6\xc3\xb8\xc3\xa5' # the interpreter prints the unicode object like so 
    >>> unicode('\xc3\xa6\xc3\xb8\xc3\xa5', 'latin1') 
    u'\xc3\xa6\xc3\xb8\xc3\xa5' 
    >>> '\xc3\xa6\xc3\xb8\xc3\xa5'.decode('latin1') 
    u'\xc3\xa6\xc3\xb8\xc3\xa5' 

您通常解碼,只要你從網絡或從磁盤文件接收字符串數據字節的字符串。

我相信有一些變化的Unicode處理在Python 3,所以上面可能是不適合蟒蛇正確3.

一些很好的鏈接:

+6

你沒有回答OP的問題。 OP想知道什麼是str.encode()和unicode.decode()。你只是重複了原始問題中提到的內容。 – stuckintheshuck 2013-09-04 17:20:17

11

anUnicode。 編碼(「編碼」)導致對象,並且可以一個unicode對象

ASTRING上被調用。 解碼('編碼')會產生一個對象,並且可以在給定編碼中編碼的字符串上調用。


一些更多的解釋:

您可以創建一些Unicode的對象,它沒有任何編碼集。它被Python存儲在內存中的方式不值得關注。你可以搜索它,分割它並調用你喜歡的任何字符串操作函數。

但是有一段時間,當你想將你的unicode對象打印到控制檯或某些文本文件中。所以你必須編碼它(例如 - 在UTF-8中),你可以調用encode('utf-8'),你會得到一個字符串'\\someNumber >'裏面,這是完美的打印。

然後,再次 - 你想要做的正好相反 - 在UTF-8編碼的讀取字符串,並把它作爲一個統一的,所以\ U360將是一個字符,而不是5.然後你解碼字符串(使用選定的編碼)並獲得unicode類型的全新對象。你可以選擇一些變形編碼,如'zip','base64','rot',其中一些將從字符串轉換爲字符串,但我相信最常見的情況是涉及UTF-8/UTF-16和字符串。

0

簡單的答案是它們是彼此完全相反的。

讓我們用一個例子來說明:

計算機使用字節的非常基本單位來存儲和處理信息,這是毫無意義的人的眼睛。

例如'\ xe4 \ xb8 \ xad \ xe6 \ x96 \ x87'是兩個中文字符的表示,但計算機只知道(意思是打印或存儲)它們是中文字符要查找中文單詞,在這種情況下,它是「utf-8」字典,如果您查看不同或錯誤的字典(使用不同的解碼方法),它將無法正確顯示預期的中文單詞。

在上述情況下,計算機查找中文單詞的過程是decode()。

而計算機將中文寫入計算機內存的過程是encode()。

所以編碼信息是原始字節,解碼信息是原始字節和引用字典的名稱(但不是字典本身)。