2010-10-20 23 views
1

的,當我從Eclipse的IDE中運行我的程序下面的代碼段工程完美:Python中的Unicode進出IDE

address_name = self.text_ctrl_address.GetValue().encode('utf-8') 
self.address_list = [i for i in data if address_name.upper() in i[5].upper().encode('utf-8')] 

但運行在同一塊直接與Python代碼的時候,我得到一個「 UnicodeDecodeError錯誤」。

IDE做什麼不同,它不會落在這個錯誤?

ps:我編碼這兩個unicode字符串,因爲它是測試一個字符串與另一個包含字母如ñ或ç的唯一方法。

編輯:

對不起,我應該給更多的細節:這段代碼屬於與wxPython的內置的對話框。 GetValue()函數從行編輯小部件獲取文本,並嘗試將這段文本與數據庫匹配。該程序在Windows上運行(因此,也許上面的邁克爾Shopsin可能是正確的(「Win-1252到UTF-8是一個嚴重的麻煩」)。我讀過很多次,我應該總是使用unicode,避免編碼,但如果我不編碼,某些字符串方法似乎不能很好地工作,取決於單詞中的字符(我在西班牙,所以很多非ASCII字符)。直接我的意思是「雙擊」文件它自己,而不是從IDE內運行

+0

「直接」?你的意思是從命令提示符?什麼OS?什麼是您的控制檯的編碼? – 2010-10-20 14:53:14

+0

我不知道Eclipse,但是你是什麼意思「這是測試一個字符串與另一個字符串的唯一方法」?在現代Python中,如果你沒有做輸入或輸出(來自文件,數據庫或網絡),即使在這種情況下許多API透明地處理unicode,你也不需要擔心編碼/解碼。什麼是GetValue()方法?哪個庫? – 2010-10-20 14:55:33

+0

Win-1252到UTF-8是一個嚴重的麻煩,我第二個Kelmer關於穩定編碼的問題。 – 2010-10-20 15:09:47

回答

0

我可以解決從UTF-8更改編碼爲cp1252(Windows西歐)的問題,顯然UTF-8無法編碼一些Windows字符。 Shopsin以上洞察洞察

該程序在Windows上運行,並使用WxPython對話框,獲取行ed的值它將小部件和字符串匹配到數據庫。

謝謝大家的關注,我希望這篇文章能夠幫助未來的人們解決類似的問題。

+0

沒問題,我用很多語言處理過這個問題。 – 2010-10-21 14:49:36

+0

*「顯然UTF-8無法編碼一些Windows字符。」* - 這是不正確的。 'cp1252'支持'0x100'字符,'utf-8'支持超過一百萬個Unicode字符。 'utf-8'可能會在無效的Unicode文本上失敗,例如,在一個單獨的替代項上:'u'\ udce2''。 'utf-8'支持'cp1252'支持的所有字符。 – jfs 2015-08-24 09:37:39

1

UnicodeDecodeError表示錯誤發生在解碼的一個字節串到Unicode中。

>>> u"\N{EM DASH}".encode('utf-8').encode('utf-8') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128) 

u"\N{EM DASH}".encode('utf-8')是一個字節串並調用.encode('utf-8')的第二次導致了潛在隱性.decode(sys.getdefaultencoding())

特別是,如果你試圖編碼字節字符串代替Unicode字符串Python的2可能發生到UnicodeDecodeError

IDE做什麼不同,它不會落在這個錯誤?

它可能工作在IDE因爲它改變sys.getdefaultencoding()utf-8不應做。如您的問題所示,它可能會隱藏錯誤。在一般情況下,它也可能會破壞不希望Python的2

我同時編碼unicode字符串非ASCII sys.getdefaultencoding()第三方庫,因爲它是測試對像ñ另一個包含字母一根弦的唯一途徑或ç。

您應該use unicodedata.normalize() instead

>>> import unicodedata 
>>> a, b = u'\xf1', u'n\u0303' 
>>> print(a) 
ñ 
>>> print(b) 
ñ 
>>> a == unicodedata.normalize('NFC', b) 
True 

注意:你的問題的代碼可能會產生令人驚訝的結果:

#XXX BROKEN, DON'T DO IT 
...address_name.upper() in i[5].upper().encode('utf-8')... 

address_name.upper()電話bytes.upper方法而i[5].upper()電話unicode.upper方法。前者不支持Unicode,它可能取決於當前的語言環境,後者是更好,但執行不區分大小寫的比較,使用.casefold()方法代替:

key = unicode_address_name.casefold() 
... if key == i[5].casefold()... 

在一般情況下,如果需要unicode字符串,然後進行排序你可以使用icu.Collator。比較默認的排序辭書:

>>> L = [u'sandwiches', u'angel delight', u'custard', u'éclairs', u'glühwein'] 
>>> sorted(L) 
[u'angel delight', u'custard', u'gl\xfchwein', u'sandwiches', u'\xe9clairs'] 

與秩序en_GB區域:

>>> import icu # PyICU 
>>> collator = icu.Collator.createInstance(icu.Locale('en_GB')) 
>>> sorted(L, key=collator.getSortKey) 
[u'angel delight', u'custard', u'\xe9clairs', u'gl\xfchwein', u'sandwiches']