Python Popen未能在Windows PowerShell中使用正确的编码
我正在Windows PowerShell中运行Python脚本,该脚本应该使用Popen运行另一个程序,然后通过管道将该程序的输出(实际上是Mercurial)用于我的脚本。尝试在PowerShell中执行脚本时,出现编码错误 我很确定这是因为Python在获取Popen调用的输出时没有使用PowerShell使用的正确编码问题是我不知道如何告诉Python使用正确的编码。Python Popen未能在Windows PowerShell中使用正确的编码,python,powershell,unicode,mercurial,Python,Powershell,Unicode,Mercurial,我正在Windows PowerShell中运行Python脚本,该脚本应该使用Popen运行另一个程序,然后通过管道将该程序的输出(实际上是Mercurial)用于我的脚本。尝试在PowerShell中执行脚本时,出现编码错误 我很确定这是因为Python在获取Popen调用的输出时没有使用PowerShell使用的正确编码问题是我不知道如何告诉Python使用正确的编码。 我的脚本看起来像 # -*- coding: utf-8 -*- #... some imports proc = P
我的脚本看起来像
# -*- 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)中得到以下错误:
我尝试了以下操作,但没有成功(即,上述错误报告保持不变):
- 从我的脚本中删除行
#-*-coding:utf-8-*-
- 删除脚本中通过Popen运行Mercurial的
选项--encoding UTF-8
- 在执行我的脚本之前,在PowerShell中将编码更改为
chcp 850
- 我在其他堆栈溢出答案中发现了许多其他杂项Python攻击
hgapi.py
是给出错误的脚本
更新: 该脚本正在被调用,其编码设置如下
sys.setdefaultencoding("utf-8")
这一行看起来很重要,因为如果我把它注释掉,我会得到一个不同的错误:
UnicodeDecoreError: 'ascii' codec cant decode byte 0xe3 in position 0: ordinal not in range(128)
尝试将编码更改为
cp1252
。Windows中的Popen希望shell命令编码为cp1252
。这似乎是一个bug,在Python 3.X中,它似乎通过子流程
模块得到了修复:
更新:
您的问题可能可以通过Django模块的smart_str功能解决
使用此代码:
from django.utils.encoding import smart_str, smart_unicode
# the cmd should contain sthe string with the commsnd that you want to execute
smart_cmd = smart_str(cmd)
subprocess.Popen(smart_cmd)
您可以找到有关如何在Windows上安装Django的信息。
您可以先安装,然后通过启动来安装Django
具有管理员权限的命令shell,并运行此命令:
pip install Django
这将在Python安装的site packages目录中安装Django。在使用来自“未来”的“导入unicode”文本的
后,我开始出现相同的错误,但代码的不同部分:
out, err = [x.decode("utf-8") for x in proc.communicate()]
给出了错误
UnicodeDecodeError: 'utf8' codec cant decode byte 0xe3 in position 33 ....
实际上,x
是一个包含\xe3
(在cp1252中是ã
)的字节字符串。因此,我没有使用x.decode('utf-8')
,而是使用x.decode('windows-1252')
,这没有给我带来任何bug。为了支持任何类型的编码,我最终使用了x.decode(sys.stdout.encoding)
问题已解决。
这是在装有Windows 7 Starter计算机的Python 3.2.2中实现的,但同一台计算机上的Python 2.7也正常工作。通过什么将编码更改为cp1252chcp 1252
在PowerShell中没有帮助。@STALTZ Try$outpuneCoding=[控制台]::outpuneCoding
@STALTZ很抱歉,也许我更新的答案可以帮助您,但您必须安装一个新模块,即djangosmart_str
是一个非常有用的函数。您可以在这里找到更多信息:我还没有尝试过您的Django解决方案@ThanasisPetsas,因为我认为应该有一些基本的Python解决方案。无论如何,谢谢,如果我没有找到其他解决方案,我最终可以使用Django。当使用时,您是否也有同样的问题?因为您使用的是python,所以看起来很自然。该项目以前使用mercurial内部api,但我改用命令行api,因为这是官方的稳定api。除了扩展之外,不应使用内部api。这更像是args
数组的问题,因为在list2cmdline
中引发了异常。可能args
或self.path
是字节字符串而不是Unicode字符串?在Windows上,通常希望尽可能使用Unicode字符串hgapi.py
将所有字符串文字转换为Unicode文字(来自uuu未来uuu导入Unicode_u文字
),而hypergrasscore.py
可能也会这样做。@Philipp,这很有意义。但是,我添加了来自uuu future uuuu导入unicode u文本的,仍然得到相同的错误。事实上,我甚至在调用hgapi.py的hypergrasscore.py脚本中的字符串(u'string'
)之前包含了u
,但没有成功=/有趣-在我的例子中,sys.stdout.encoding
没有-locale.getpreferredencoding()会起作用吗?
out, err = [x.decode("utf-8") for x in proc.communicate()]
UnicodeDecodeError: 'utf8' codec cant decode byte 0xe3 in position 33 ....