我之前已经问过这样的问题了。但我没有找到解决方案。
我想在子程序模块中使用我的python文件中定义的unicode文字。但我没有得到我需要的结果。例如以下代码
# -*- 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上运行,但我希望解决方案与平台无关。
答案 0 :(得分:2)
你的第一次尝试是最好的。
您实际上已经转换了UTF8中的2个unicode字符u'你好'
(或u'\u4f60\u597d'
)所有提供b'\xe4\xbd\xa0\xe5\xa5\xbd'
的内容。
您可以在IDLE中控制它,完全支持unicode以及b'\xe4\xbd\xa0\xe5\xa5\xbd'.decode('utf-8')
返回你好
的位置。控制它的另一种方法是将脚本输出重定向到一个文件,并使用兼容UTF-8的编辑器打开它:再次,你会看到你想要的。
但问题是Windows控制台不支持完整的unicode。这取决于:
如果您知道包含字符字形的代码页(我没有),您可以尝试将其插入到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
窗口!
答案 1 :(得分:1)
结论:注意字符编码(这里有三种不同的字符编码)。如果您需要可移植的Unicode支持(将参数作为Unicode传递,不对它们进行编码)或确保使用环境中的当前字符编码来表示数据(在Python 2上使用sys.getfilesystemencoding()
进行编码),请使用Python 3在第二个代码示例中做。)
第一个代码示例不正确。效果与(在IDLE中运行 - py -3 -midlelib
)相同:
>>> print(u'你好'.encode('utf-8').decode('mbcs')) #XXX DON'T DO IT!
ä½ å¥½
其中mbcs
编解码器使用您的Windows ANSI code page(通常为cp1252
字符编码 - 可能会有所不同,例如俄语Windows上的cp1251
。
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)。请参阅Unicode filenames on Windows with Python & subprocess.Popen()。