2010-10-20 57 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']