Python popen() - 通信(str.encode(编码="utf-8",错误="ignore"))崩溃

Python popen() - communicate( str.encode(encoding="utf-8", errors="ignore") ) crashes

在 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(...) 的参数是什么。当您省略错误部分时,这同样适用。

您不应该在 class 本身上调用 .encode()。您可能想要做的是

p1.communicate("FOOBAR".encode("utf-8"))

您收到的错误消息意味着 encode() 函数没有任何可编码的内容,因为您是在 class 上调用它的,而不是在实例上调用的(然后将作为self 参数到 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()