我在 Windows 7 终端中使用 Python 解释器。
我正在尝试了解 unicode 和编码。
我输入:
>>> s='ë'
>>> s
'\x89'
>>> u=u'ë'
>>> u
u'\xeb'
问题1:为什么字符串
s
中使用的编码与unicode字符串u
中使用的编码不同?
我继续,然后输入:
>>> us=unicode(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0x89 in position 0: ordinal
not in range(128)
>>> us=unicode(s, 'latin-1')
>>> us
u'\x89'
问题2:我尝试使用
latin-1
编码来将字符串转换为unicode字符串(实际上,我首先尝试了很多其他编码,包括utf-8
)。如何找出终端使用哪种编码来编码我的字符串?
问题3:如何让终端将
ë
ë
而不是'\x89'
或u'xeb'
?print(s)
完成工作。
我已经看过这个相关的SO问题,但没有任何线索:在Windows上设置Python终端编码
Unicode 不是一种编码。您编码为字节字符串并解码为 Unicode:
>>> '\x89'.decode('cp437')
u'\xeb'
>>> u'\xeb'.encode('cp437')
'\x89'
>>> u'\xeb'.encode('utf8')
'\xc3\xab'
Windows 终端使用 DOS 的旧代码页。对于美国 Windows 来说是:
>>> import sys
>>> sys.stdout.encoding
'cp437'
Windows 应用程序使用 Windows 代码页。 Python 的 IDLE 将显示 Windows 编码:
>>> import sys
>>> sys.stdout.encoding
'cp1252'
您的结果可能会有所不同。
我并不是冒险说“终端”,更恰当地说,Windows 7 附带的“DOS 提示符”绝对是垃圾。它在 Windows 95、NT、XP、Vista 和 7 中很糟糕。也许他们用 Powershell 修复了它,我不知道。然而,它表明了当时困扰微软操作系统开发的问题。
设置
PYTHONIOENCODING
环境变量,然后将输出重定向到文件。
set PYTHONIOENCODING=utf-8
./myscript.py > output.txt
然后使用 Notepad++ 您可以看到输出的 UTF-8 版本。
win-unicode-console 可以解决您的问题。你应该尝试一下
pip install win-unicode-console
如果您对 Python 和命令行输出问题的深入讨论感兴趣,请查看 Python 问题 1602。否则,只需使用 win-unicode-console 包即可。
py -m run script.py
按脚本运行它,或者您可以按照他们的指示将
win_unicode_console.enable()
添加到每个调用中,方法是将其添加到 usercustomize
或 sitecustomize
。
以防其他人在搜索时看到此页面 最简单的方法是先在终端中设置代码页
CHCP 65001
然后运行你的程序。
对我来说效果很好。 对于电源外壳,从
开始powershell.exe -NoExit /c "chcp.com 65001"
在阅读教程中的本节后,请通读有关unicode的Python HOWTO
在 Python 中创建 Unicode 字符串就像创建普通字符串一样简单:
>>> u'Hello World !'
u'Hello World !'
要回答你的第一个问题,它们是不同的,因为只有使用
u''
时,你才会创建一个 unicode 字符串。
第二个问题:
sys.getdefaultencoding()
返回默认编码
但引用链接:
刚接触 Unicode 的 Python 用户有时会被 sys.getdefaultencoding() 返回的默认编码所吸引。关于默认编码,您应该了解的第一件事是您不需要关心它。它的值应该是 'ascii' 并且在将字节字符串 StrIsNotAString 转换为 unicode 字符串时使用它。
您已经回答了问题 1:第一个字符串是编码的字节字符串,但第二个字符串根本不是编码,它指的是 unicode 代码点,即“带有分音符号的拉丁文小写字母 E” “是十六进制
eb
。
现在,第一个编码是什么的问题是一个有趣的问题。我通常期望它是 utf-8,或者,因为你使用的是 Windows,ISO-8859-1 或 Win-1252(它们不完全相同,但足够接近)。然而,该字母在 utf-8 中的正常表示是
c3 ab
,而在 Win-1252 中它实际上与 unicode 代码点相同 - 即十六进制 eb
。所以,这有点神秘。
看来您正在使用代码页CP850,这是有道理的,因为这是 DOS 的历史代码页,已被转移到终端窗口。
>>> s
'\x89'
>>> us=unicode(s,'CP850')
>>> us
u'\xeb'
实际上,unicode对象没有 “编码”。你应该阅读 python中的Unicode以避免常量 困惑。这个演示看起来 足够的 - http://farmdev.com/talks/unicode/ .
您使用的是俄语版本 窗户,对吗?您终端使用 cp1251.
正如您所了解的:
>>> a = "ё"
>>> a
'\xf1'
>>> print a
ё
出现此类错误时您是否打开任何文件? 如果是这样,请尝试使用
打开它import codecs
f = codecs.open('filename.txt','r','utf-8')