Python popen () - communicate (str.encode (encoding= "utf-8", errors= "ignore")) сбой
использование Python 3.4.3 в Windows.
мой скрипт запускает небольшую 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'кодек не может декодировать байт 0x9d в позиции 135: отображение символов в '.
теперь я хочу игнорировать ошибки:
out, err = p1.communicate(str.encode(encoding="utf-8", errors="ignore"))
это приводит к более интересной ошибке, я не нашел помощи для использования google:
TypeError: дескриптору 'encode' объекта ' str ' нужен аргумент
поэтому кажется, что python даже не знает больше, какие аргументы для str.кодировать.(..) АР. То же самое относится и к части "ошибки".
2 ответов
universal_newlines=True
включает текстовый режим. В сочетании с stdout=PIPE
, это заставляет декодировать вывод дочернего процесса с помощью locale.getpreferredencoding(False)
это не utf-8 в Windows. Вот почему вы видите UnicodeDecodeError
.
чтобы прочитать вывод подпроцесса с помощью кодировки utf-8, drop 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()
без уважительной причины.
вы не должны называть .encode()
на самом классе. Что вы, вероятно, хотите сделать что-то вроде
p1.communicate("FOOBAR".encode("utf-8"))
сообщение об ошибке вы получаете означает, что encode()
функция не имеет ничего для кодирования, так как вы вызвали ее в классе, а не в экземпляре (который затем будет передан как до encode()
).