【发布时间】:2012-04-17 01:19:11
【问题描述】:
我在 Windows PowerShell 中运行我的 Python 脚本,该脚本应该使用 Popen 运行另一个程序,然后通过管道输出该程序的输出(实际上是 Mercurial)以在我的脚本中使用。当我尝试在 PowerShell 中执行脚本时遇到编码错误。
我很确定它正在发生,因为在获取 Popen 调用的输出时,Python 没有使用 PowerShell 使用的正确编码。 问题是我不知道如何告诉 Python 使用正确的编码。
我的脚本看起来像
# -*- coding: utf-8 -*-
#... some imports
proc = Popen(["hg", "--cwd", self.path, "--encoding", "UTF-8"] + list(args), stdout=PIPE, stderr=PIPE)
#... other code
当我在 Linux 上运行这个脚本时,我没有任何问题。我还可以使用 PowerShell 在 Windows 7 Home Premium 64 位中运行脚本,没有任何问题。这个Windows 7中的PowerShell使用的是代码页850,即chcp的输出是850("ibm850")。
然而,当我使用默认编码为 cp437 (chcp = 437 的 PowerShell 在 Windows 7 Starter 32 位 中运行脚本时),我从 Python(2.7.2 版)收到以下错误:
File "D:\Path\to\myscript.py", line 55, in hg_command
proc = Popen(["hg", "--cwd", self.path, "--encoding", "UTF-8"] + list(args), stdout=PIPE, stderr=PIPE)
File "C:\Program files\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Program files\Python27\lib\subprocess.py", line 852, in _execute_child
args = list2cmdline(args)
File "C:\Program files\Python27\lib\subprocess.py", line 615, in list2cmdline
return ''.join(result)
UnicodeDecodeError: 'utf8' codec cant decode byte 0xe3 in position 0: unexpected end of data
我尝试了以下方法,但没有成功(即上述错误报告保持不变):
- 从我的脚本中删除
# -*- coding: utf-8 -*-行。 - 删除在我的脚本中通过 Popen 运行 Mercurial 的
-- encoding UTF-8选项。 - 在执行我的脚本之前,在 PowerShell 中将编码更改为
chcp 850。 - 我在其他 Stack Overflow 答案中发现了许多其他杂项 Python hack。
关于我的具体细节,我的完整源代码可在here in BitBucket 获得。 hgapi.py 是给出错误的脚本。
更新: 这个other script正在调用脚本,它正在设置这样的编码
sys.setdefaultencoding("utf-8")
这一行看起来很重要,因为如果我把它注释掉,我会得到一个不同的错误:
UnicodeDecoreError: 'ascii' codec cant decode byte 0xe3 in position 0: ordinal not in range(128)
【问题讨论】:
-
您在使用mercurial api时是否有同样的问题?由于您使用的是 python,所以它看起来很自然。
-
项目之前使用的是mercurial的内部api,但是因为是官方稳定的,所以我切换到了命令行api。除扩展外,不应使用内部 api。
-
这看起来更像是
args数组的问题,因为在list2cmdline中引发了异常。也许args或self.path是字节字符串而不是Unicode 字符串? -
在 Windows 上,您通常希望尽可能使用 Unicode 字符串。
hgapi.py将所有字符串文字转换为 Unicode 文字 (from __future__ import unicode_literals),hypergrasscore.py可能也应该这样做。 -
@Philipp,这是有道理的。但是,我添加了
from __future__ import unicode_literals,但仍然出现同样的错误。事实上,我什至在调用 hgapi.py 的 hypergrasscore.py 脚本中包含u之前的字符串 (u'string'),但没有成功。 =/
标签: python powershell unicode mercurial