在Windows上使用Python 3.4.3。
我的脚本在控制台中运行一个小程序,应该得到输出:
import subprocess
p1 = subprocess.Popen([ ... ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out, err = p1.communicate(str.encode("utf-8"))
这导致正常
'UnicodeDecodeError:'charmap'编解码器无法解码位置135中的字节0x9d:字符映射到<未定义>”
现在我想忽略错误:
out, err = p1.communicate(str.encode(encoding="utf-8", errors="ignore"))
这导致了一个更有趣的错误,我发现没有帮助使用谷歌:
TypeError:'str'对象的描述符'encode'需要一个参数
所以似乎python甚至不知道str.encode(...)的参数是什么。如果省略错误部分也同样适用。
答案 0 :(得分:12)
universal_newlines=True
启用文字模式。结合stdout=PIPE
,它强制解码子进程'在Windows上使用不是utf-8的locale.getpreferredencoding(False)
输出。这就是您看到UnicodeDecodeError
。
阅读子流程'输出使用utf-8编码,删除universal_newlines=True
:
#!/usr/bin/env python3
from subprocess import Popen, PIPE
with Popen(r'C:\path\to\program.exe "arg 1" "arg 2"',
stdout=PIPE, stderr=PIPE) as p:
output, errors = p.communicate()
lines = output.decode('utf-8').splitlines()
str.encode("utf-8")
相当于"utf-8".encode()
。除非您设置.communicate()
并且子进程期望stdin=PIPE
bytestring作为输入,否则无法将其传递给b'utf-8'
。
str.encode(encoding="utf-8", errors="ignore)
的格式为klass.method(**kwargs)
。 .encode()
方法需要self
(字符串对象),这就是您看到TypeError
的原因。
>>> str.encode("abc", encoding="utf-8", errors="ignore") #XXX don't do it
b'abc'
>>> "abc".encode(encoding="utf-8", errors="ignore")
b'abc'
如果没有充分理由,请勿使用klass.method(obj)
代替obj.method()
。
答案 1 :(得分:2)
你不应该在课堂上调用In [1]: print str.find.__doc__
S.find(sub [,start [,end]]) -> int
Return the lowest index in S where substring sub is found,
such that sub is contained within S[start:end]. Optional
arguments start and end are interpreted as in slice notation.
Return -1 on failure.
。您可能想要做的是像
.encode()
您获得的错误消息意味着p1.communicate("FOOBAR".encode("utf-8"))
函数无需编码,因为您在类上调用它,而不是在实例上调用(然后将其作为encode()
传递参数self
)。