在 Windows 上使用 Python 3.4.3。
我的脚本在控制台中运行一个小的 java 程序,应该得到输出:
import subprocess
p1 = subprocess.Popen([ ... ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
out, err = p1.communicate(str.encode("utf-8"))
这导致一个正常的
'UnicodeDecodeError: 'charmap' codec can't decode byte 0x9d in position 135: character maps to < undefined>'.
现在我想忽略错误:
out, err = p1.communicate(str.encode(encoding="utf-8", errors="ignore"))
这导致了一个更有趣的错误,我发现使用 google 没有帮助:
TypeError: descriptor 'encode' of 'str' object needs an argument
所以看起来 python 甚至不知道 str.encode(...) 的参数是什么。当您省略错误部分时,这同样适用。
最佳答案
universal_newlines=True
启用文本模式。结合 stdout=PIPE
,它强制使用 locale.getpreferredencoding(False)
对子进程的输出进行解码,这在 Windows 上不是 utf-8。这就是您看到 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
并且子进程需要 b'utf-8'
bytestring 作为输入。
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()
。
关于Python popen() - 通信(str.encode(编码 ="utf-8",错误 ="ignore"))崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33283603/