2009-04-27 31 views
4

我將terminal.app設置爲接受utf-8並在bash中可以輸入unicode字符並複製並粘貼它們,但是如果我啓動python殼我不能,如果我嘗試解碼的unicode我得到的錯誤:無法在os上解碼utf-8字符串x terminal.app

>>> wtf = u'\xe4\xf6\xfc'.decode() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) 
>>> wtf = u'\xe4\xf6\xfc'.decode('utf-8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/encodings/utf_8.py", line 16, in decode 
    return codecs.utf_8_decode(input, errors, True) 
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128) 

任何人都知道我做錯了嗎?

+0

[這](http://stackoverflow.com/問題/ 368805/python-unicodedecodeerror-am-i-misunderstanding-encode/370199#370199)在有關編碼/解碼的相關問題中回答可能會有所幫助。 – tzot 2009-04-27 10:12:00

回答

18

我認爲這是所有的地方編碼/解碼的混亂。你開始用Unicode的對象:

u'\xe4\xf6\xfc' 

這是一個unicode的對象,這三個角色是「AOU」的Unicode代碼點。如果你想將它們變成UTF-8,你必須編碼他們:

>>> u'\xe4\xf6\xfc'.encode('utf-8') 
'\xc3\xa4\xc3\xb6\xc3\xbc' 

產生的六個字符是「AOU」的UTF-8表示。

如果您致電decode(...),則嘗試將字符解釋爲某些仍需轉換爲unicode的編碼。既然它已經是Unicode,這是行不通的。你的第一次調用嘗試一個Ascii到Unicode的轉換,第二次調用一個Utf-8到Unicode的轉換。由於u'\xe4\xf6\xfc'既不是有效的Ascii也不是有效的Utf-8,所以這些轉換嘗試失敗。

此外,'\xe4\xf6\xfc'也是「äöü」的Latin1/ISO-8859-1編碼。如果你寫一個正常的Python字符串(沒有前導「U」標誌着它爲Unicode),你可以用decode('latin1')它轉換成Unicode的對象:

>>> '\xe4\xf6\xfc'.decode('latin1') 
u'\xe4\xf6\xfc' 
4

我認爲你有編碼和解碼向後。您將Unicode編碼爲字節流,並將字節流解碼爲Unicode。

Python 2.6.1 (r261:67515, Dec 6 2008, 16:42:21) 
[GCC 4.0.1 (Apple Computer, Inc. build 5370)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> wtf = u'\xe4\xf6\xfc' 
>>> wtf 
u'\xe4\xf6\xfc' 
>>> print wtf 
äöü 
>>> wtf.encode('UTF-8') 
'\xc3\xa4\xc3\xb6\xc3\xbc' 
>>> print '\xc3\xa4\xc3\xb6\xc3\xbc'.decode('utf-8') 
äöü 
+1

嗯。 UTF-8是一種已編碼的字節流,因此,儘管不會倒退,但至少可以橫向調整:)也許你的意思是Unicode而不是UTF-8。我會編輯你的文章並讓你決定。 – tzot 2009-04-27 10:09:34

+0

是的,你是對的。謝謝! – 2009-04-27 14:31:30

2

入門教程的Unicode strings部分解釋得好:

要使用特定的編碼Unicode字符串轉換成一個8位的串,Unicode對象提供的編碼()方法,它一個參數,即編碼的名稱。編碼的小寫名稱是首選。

>>> u"äöü".encode('utf-8') 
'\xc3\xa4\xc3\xb6\xc3\xbc' 
+1

是不是你解碼字符,然後在你的最後一行? – 2009-04-27 02:28:47

3
>>> wtf = '\xe4\xf6\xfc' 
>>> wtf 
'\xe4\xf6\xfc' 
>>> print wtf 
��� 
>>> print wtf.decode("latin-1") 
äöü 
>>> wtf_unicode = unicode(wtf.decode("latin-1")) 
>>> wtf_unicode 
u'\xe4\xf6\xfc' 
>>> print wtf_unicode 
äöü