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()。
我知道以前有人问过这样的问题。但我没有找到解决方案。
我想将在我的 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()。