python:Windows终端中的unicode,使用的编码?

问题描述 投票:0回答:8

我在 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终端编码

windows python-2.7 unicode terminal
8个回答
13
投票

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'

您的结果可能会有所不同。


6
投票

避免使用 Windows 终端

我并不是冒险说“终端”,更恰当地说,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

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


2
投票

以防其他人在搜索时看到此页面 最简单的方法是先在终端中设置代码页

CHCP 65001

然后运行你的程序。

对我来说效果很好。 对于电源外壳,从

开始
powershell.exe -NoExit /c "chcp.com 65001"

来自python:Windows终端中的unicode,使用的编码?


1
投票

在阅读教程中的本节后,请通读有关unicode的Python HOWTO

在 Python 中创建 Unicode 字符串就像创建普通字符串一样简单:

>>> u'Hello World !'
u'Hello World !'

要回答你的第一个问题,它们是不同的,因为只有使用

u''
时,你才会创建一个 unicode 字符串。

第二个问题:

sys.getdefaultencoding()

返回默认编码

但引用链接

刚接触 Unicode 的 Python 用户有时会被 sys.getdefaultencoding() 返回的默认编码所吸引。关于默认编码,您应该了解的第一件事是您不需要关心它。它的值应该是 'ascii' 并且在将字节字符串 StrIsNotAString 转换为 unicode 字符串时使用它。


1
投票

您已经回答了问题 1:第一个字符串是编码的字节字符串,但第二个字符串根本不是编码,它指的是 unicode 代码点,即“带有分音符号的拉丁文小写字母 E” “是十六进制

eb

现在,第一个编码是什么的问题是一个有趣的问题。我通常期望它是 utf-8,或者,因为你使用的是 Windows,ISO-8859-1 或 Win-1252(它们不完全相同,但足够接近)。然而,该字母在 utf-8 中的正常表示是

c3 ab
,而在 Win-1252 中它实际上与 unicode 代码点相同 - 即十六进制
eb
。所以,这有点神秘。


1
投票

看来您正在使用代码页CP850,这是有道理的,因为这是 DOS 的历史代码页,已被转移到终端窗口。

>>> s
'\x89'
>>> us=unicode(s,'CP850')
>>> us
u'\xeb'

1
投票
  1. 实际上,unicode对象没有 “编码”。你应该阅读 python中的Unicode以避免常量 困惑。这个演示看起来 足够的 - http://farmdev.com/talks/unicode/ .

  2. 您使用的是俄语版本 窗户,对吗?您终端使用 cp1251.


1
投票

正如您所了解的:

>>> a = "ё"
>>> a
'\xf1'
>>> print a
ё

出现此类错误时您是否打开任何文件? 如果是这样,请尝试使用

打开它
import codecs
f = codecs.open('filename.txt','r','utf-8')
© www.soinside.com 2019 - 2024. All rights reserved.