我在python中玩unicode

因此,有一个简单的脚本:

# -*- coding: cp1251 -*-

print 'юникод'.decode('cp1251')
print unicode('юникод', 'cp1251')
print unicode('юникод', 'utf-8')


在cmd中,我已将编码切换为Active code page: 1251

并有输出:

СЋРЅРёРєРѕРґ
СЋРЅРёРєРѕРґ
юникод


我有点困惑。

由于我已将编码指定为cp1251,所以我希望它会被正确解码。

但是结果是一些垃圾代码点被解释了。
我知道'юникод'只是一个字节,如:
'\xd1\x8e\xd0\xbd\xd0\xb8\xd0\xba\xd0\xbe\xd0\xb4'

但是有一种方法可以通过cp1251在终端中获得正确的输出吗?
我应该手动构建字节字符串吗?

好像我误解了一些东西。

最佳答案

我想我能理解你发生了什么。最后一行给了我提示,您的垃圾箱代码点已确认。您尝试显示cp1251字符,但是您的编辑器配置为使用utf8。

# -*- coding: cp1251 -*-仅由Python解释器用来转换ASCII范围之外的源python文件中的字符。而且无论如何,它仅用于Unicode乱码,因为来自原始源的字节给出er ...字节字符串中的字节完全相同。一些文本编辑器足够友好地自动使用该行(IDLE编辑器是),但是我对此不太自信,例如当我使用gvim时,总是手动切换为正确的编码。简短的故事:# -*- coding: cp1251 -*-在您的代码中未使用,只能误导读者,因为它不是实际的编码。

如果您想确定源代码中的内容,则最好使用显式转义符。在代码页1251中,单词юникод由以下字符组成:'\xfe\xed\xe8\xea\xee\xe4'

如果您编写此源:

txt = '\xfe\xed\xe8\xea\xee\xe4'
print txt
print txt.decode('cp1251')
print unicode(txt, 'cp1251')
print unicode(txt, 'utf-8')


并在配置为使用CP1251字符集的控制台中执行它,前三行将输出юникод,最后一行将引发UnicodeDecodeError异常,因为输入不再是有效的'utf8'。

或者,如果您对当前的编辑感到满意,则可以编写:

# -*- coding: utf8 -*-

txt = 'юникод'.decode('utf8').encode('cp1251') # or simply txt = u'юникод'.encode('cp1251')
print txt
print txt.decode('cp1251')
print unicode(txt, 'cp1251')
print unicode(txt, 'utf-8')


应该给出相同的结果-但是现在声明的源编码应该是python源的实际编码。



顺便说一句,原生使用unicode的Python 3.5 IDLE确认:

>>> 'СЋРЅРёРєРѕРґ'.encode('cp1251').decode('utf8')
'юникод'

09-12 10:51