Python 子进程回显 unicode 文字

Python subprocess echo a unicode literal

我知道以前有人问过这样的问题。但我没有找到解决方案。

我想将在我的 python 文件中定义的 unicode 文字与 subprocess 模块一起使用。但我没有得到我需要的结果。例如下面的代码

# -*- coding: utf-8 -*-
import sys
import codecs
import subprocess
cmd = ['echo', u'你好']
new_cmd = []
for c in cmd:
    if isinstance(c,unicode):
        c = c.encode('utf-8')
    new_cmd.append(c)
subprocess.call(new_cmd)

打印出来

你好

如果我将代码更改为

# -*- coding: utf-8 -*-
import sys
import codecs
import subprocess
cmd = ['echo', u'你好']
new_cmd = []
for c in cmd:
    if isinstance(c,unicode):
        c = c.encode(sys.getfilesystemencoding())
    new_cmd.append(c)
subprocess.call(new_cmd)

我得到以下内容

??

在这个阶段,我只能假设我反复犯了一个简单的错误。但我很难弄清楚它是什么。当通过 python 的子进程

调用时,如何让 echo 打印出以下内容
你好

编辑:

Python的版本是2.7。我在 Windows 8 上 运行,但我希望解决方案独立于平台。

你的第一次尝试是最好的。

您实际上已将 2 个 unicode 字符 u'你好'(或 u'\u4f60\u597d')转换为 UTF8,所有这些都给出了 b'\xe4\xbd\xa0\xe5\xa5\xbd'.

您可以在完全支持 unicode 且 b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf-8') 返回 你好 的 IDLE 中控制它。另一种控制它的方法是将脚本输出重定向到一个文件,然后用一个 UTF-8 兼容的编辑器打开它:你会再次看到你想要的。

但问题是 Windows 控制台不支持完整的 unicode。这取决于:

  • 安装的代码页 - 我不知道 Windows 8,但以前的版本对 unicode 的支持很差,只能显示 256 个字符
  • 控制台中使用的字体 - 并非所有字体都具有所有字符的字形。

如果您知道包含字符字形的代码页(我不知道),您可以尝试使用 chcp 将其插入控制台,并将您的 unicode 字符串显式编码为该代码页。但是在我的法语机器上,我不知道该怎么做......除了传递一个文本文件!

正如您所说的 ConEmu,我试了一下......它与 python 3.4 !

配合得很好
chcp 65001
py -3
import subprocess
cmd = ['cmd', '/c', 'echo', u'\u4f60\u597d']
subprocess.call(cmd)

给出:

你好  
0

问题仅在 cmd.exe windows !

结论:注意字符编码(这里有三种不同的字符编码)。使用 Python 3 如果你想要可移植的 Unicode 支持(将参数作为 Unicode 传递,不要对它们进行编码)或者确保数据可以使用环境中的当前字符编码来表示(使用 sys.getfilesystemencoding() 进行编码Python 2 就像您在第二个代码示例中所做的那样)。


第一个代码示例不正确。效果同(运行 it in IDLE -- py -3 -midlelib):

>>> print(u'你好'.encode('utf-8').decode('mbcs')) #XXX DON'T DO IT!
你好

其中 mbcs 编解码器使用您的 Windows ANSI code page(通常:cp1252 字符编码——它可能不同,例如 cp1251 在俄语 Windows 上) .

Python 2 使用CreateProcess 宏启动一个子进程,相当于那里的CreateProcessA 函数。 CreateProcessA 将输入字节解释为使用您的 Windows ANSI 编码进行编码。它与 Python 源代码编码(在您的情况下为 utf-8)无关

如果您使用了错误的编码,预计会出现 mojibake。


如果输入字符可以使用 Windows 代码页表示,例如 cp1252(启用从 Unicode 到字节的编码)并且如果 echo 使用 Unicode,则您的第二个代码示例应该可以工作API 打印到 Windows 控制台,例如 WriteConsoleW() (see Python 3 package win-unicode-console -- 它启用 print(u'你好') 无论 你的 chcp ("OEM")只要控制台中的字体支持字符)字符可以使用OEM代码页(由cmd.exe使用)表示,例如cp437(运行 chcp 找出你的)。 ?? 问号表示 你好 无法使用您的控制台编码来表示。

要支持任意 Unicode 参数(包括无法使用 Windows ("ANSI") 或 MS-DOS (OEM) 代码页表示的字符),您需要 CreateProcessW 函数(由 Python 3 使用)。参见 Unicode filenames on Windows with Python & subprocess.Popen()