python - Windows 控制台编码

标签 python python-2.7 character-encoding windows-console

Windows 上的默认控制台编码是什么?看起来有时是 ANSI 编码(CP-1252),有时是 chcp 命令给出的 OEM 编码(默认为 CP-850 为西欧)。

  • 命令行参数环境变量触发 ANSI 编码(é = 0xe9):

    > chcp 850
    Active code page: 850
    > python -c "print 'é'"
    Ú
    > python -c "print '\x82'"
    é
    > python -c "print '\xe9'"
    Ú
    > $env:foobar="é"; python -c "import os; print os.getenv('foobar')"
    Ú
    
    > chcp 1252
    Active code page: 1252
    > python -c "print 'é'"
    é
    > python -c "print '\x82'"
    ,
    > python -c "print '\xe9'"
    é
    > $env:foobar="é"; python -c "import os; print os.getenv('foobar')"
    é
    
  • Python 控制台标准输入触发 OEM 编码(如果 OEM 编码为 CP-850,则 é = 0x82;如果 OEM 编码为 é = 0xe9 CP-1252):

    > chcp 850
    Active code page: 850
    > python
    >>> print 'é'
    é
    >>> print '\x82'
    é
    >>> print '\xe9'
    Ú
    > python -c "print raw_input()"
    é
    é
    
    > chcp 1252
    Active code page: 1252
    > python
    >>> print 'é'
    é
    >>> print '\x82'
    ,
    >>> print '\xe9'
    é
    > python -c "print raw_input()"
    é
    é
    

注意。 – 在这些示例中,我在 Windows 10 上使用了 Powershell 5.1 和 CPython 2.7.14。

最佳答案

首先,对于所有非 ASCII 字符,重要的是控制台编码和 Windows 区域设置,您使用的是字节字符串,而 Python 只是打印出它收到的字节。在将这些字节传递给 Python 之前,控制台将键盘输入编码为特定字节或字节序列。对于Python来说,这只是不透明的数据(0-255范围内的数字),并且print将它们传递回控制台的方式与 Python 接收它们的方式相同。

在 Powershell 中,通过命令行开关发送到 Python 的字节使用什么编码不是由 chcp 决定的。代码页,但通过控制面板中的非 Unicode 程序的语言设置(搜索区域,然后找到管理选项卡)。正是此设置编码 é到 0xE9,然后将其作为命令行参数传递给 Python。有a large number of Windows codepages使用 0xE9 表示 é (但有 no such thing as an ANSI encoding )。

这同样适用于环境变量。 Python 将 Windows 在此处使用的编码称为 MBCS codec ;您可以使用 'mbcs' 将命令行参数或环境变量解码为 Unicode编解码器,它使用 MultiByteToWideChar() WideCharToMultiByte() Windows API 函数,带有 CP_ACP标志。

使用交互式提示时,Python 将传递由 Powershell 控制台区域设置代码页编码的字节,并使用 chcp 设置。 。对于您来说,这是代码页 850,当您输入 é 时,会收到一个十六进制值 0x82 的字节。 。因为print将相同的 0x82 字节发送回同一控制台,然后控制台将 0x82 转换回 é屏幕上的字符。

仅当您使用 Unicode 文本(使用像 u'é' 这样的 unicode 字符串文字)时,Python 才会对数据进行任何解码和编码。 print写入sys.stdout ,它配置为将 Unicode 数据编码为当前语言环境(或 PYTHONIOENCODING 如果设置),因此 print u'é'将该 Unicode 对象写入 sys.stdout ,然后使用配置的编解码器将该对象编码为字节,然后将这些字节写入控制台。

生成 unicode来自 u'é' 的对象源代码文本(本身是字节序列),Python 确实必须解码给定的源代码。对于-c命令行,传入 are decoded as Latin-1 的字节。在交互式控制台中,使用区域设置。所以python -c "print u'é'"print u'é'在交互式 session 中将导致不同的输出。

值得注意的是,Python 3 始终使用 Unicode 字符串,命令行参数和环境变量通过 Windows“广泛”API 加载到 Python 中,以 UTF-16 形式访问数据,然后呈现为 ​​Unicode 字符串对象。您仍然可以以字节字符串的形式访问控制台数据和文件系统信息,但从 Python 3.6 开始,accessing the filesystem and stdin/stdout/stderr streams as binary uses UTF-8 encoded data (再次使用“广泛”API)。

关于python - Windows 控制台编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49121900/

相关文章:

python - Django 的 YearArchiveView 通用日期 View

python - Cython 重载 "no suitable method found"

Tomcat 7 org.apache.catalina.filters.AddDefaultCharsetFilter 不使用 UTF-8

python - 如何设置线程超时?

Python optparse - 选项不被读取为 false

python - 你如何列出python中的所有子进程?

linux - 当我将 python 2.7 与 sudo 一起使用时,它不起作用

python crontab 和路径

java - 如何验证 UTF-8 字符串是否包含错误编码的字符

Python 无法处理瑞典语字符