我在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”)。
但是,当我使用PowerShell运行 Windows 7 Starter 32位中的脚本时,默认情况下编码为cp437(chcp
= { {1}}),我从Python(版本2.7.2)收到以下错误:
437
我尝试过以下操作,但没有成功(即上述错误报告保持不变):
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 -*-
选项。-- encoding UTF-8
。对于我的具体细节,我的整个源代码可用here in BitBucket。 chcp 850
是提供错误的脚本。
更新 这个脚本由other script调用,它正在设置这样的编码
hgapi.py
这一行看起来很重要,因为如果我发表评论,我会得到一个不同的错误:
sys.setdefaultencoding("utf-8")
答案 0 :(得分:2)
尝试将编码更改为cp1252
。 Windows中的Popen希望shell命令编码为cp1252
。这似乎是一个错误,它似乎也通过subprocess
模块在Python 3.X中修复:http://docs.python.org/library/subprocess.html
import subprocess
subprocess.Popen(["hg", "--cwd", self.path, "--encoding", "UTF-8"] + list(args), stdout=PIPE, stderr=PIPE)
<强>更新强>
您的问题可以通过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 here上找到有关如何安装Django的信息。 您可以先安装pip,然后再开始安装Django 具有管理员权限的命令shell并运行此命令:
pip install Django
这将在您的Python安装的site-packages目录中安装Django。
答案 1 :(得分:1)
使用from __future__ import unicode_literals
后,我开始收到相同的错误,但是在代码的不同部分:
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')
,而且没有给我任何错误。为了支持任何类型的编码,我最终使用了x.decode(sys.stdout.encoding)
。 问题解决了。
这是在使用Windows 7 Starter计算机的Python 3.2.2中,但同一台计算机上的Python 2.7也能正常工作。