7

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

我想使用在我的 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 上运行,但我希望解决方案独立于平台。

4

2 回答 2

2

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

您实际上将UTF8 中的 2 个 unicode 字符u'你好'(或)转换为.u'\u4f60\u597d'b'\xe4\xbd\xa0\xe5\xa5\xbd'

您可以在完全支持 unicode 的 IDLE 中控制它,并且在哪里b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf-8')回馈你好。另一种控制它的方法是将脚本输出重定向到一个文件并使用兼容 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.exewindows上!

于 2015-05-05T15:11:16.293 回答
1

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


第一个代码示例不正确。效果和(在 IDLE 中运行 -- py -3 -midlelib)一样:

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

其中mbcscodec 使用您的Windows ANSI 代码页(通常:cp1252字符编码——它可能不同,例如cp1251在俄语 Windows 上)。

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

如果您使用错误的编码,预计您会得到 mojibake。


如果输入字符可以使用 Windows 代码页表示,例如cp1252(启用从 Unicode 到字节的编码)并且如果echo使用 Unicode API 打印到 Windows 控制台,例如WriteConsoleW()(请参阅 Python 3 包win-unicode-console——它可以启用print(u'你好') 任何你的chcp(“OEM”)只要控制台中的字体支持字符)或者可以使用 OEM 代码页(由 使用cmd.exe)来表示字符,例如cp437(运行chcp找出你的)。??问号表示你好无法使用您的控制台编码表示。

要支持任意 Unicode 参数(包括无法使用 Windows ("ANSI") 或 MS-DOS (OEM) 代码页表示的字符),您需要CreateProcessW函数(由 Python 3 使用)。使用 Python 和 subprocess.Popen()查看Windows 上的 Unicode 文件名。

于 2015-05-06T16:31:03.903 回答