Popen.communicate() 抛出 UnicodeDecodeError
Popen.communicate() throws UnicodeDecodeError
我有这个代码:
def __executeCommand(self, command: str, input: str = None) -> str:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, universal_newlines=True)
p.stdin.write(input)
output, error = p.communicate()
if (len(errors) > 0):
raise EnvironmentError("Could not generate the key: " + error)
elif (p.returncode != 0):
raise EnvironmentError("Could not generate the key. Return Value: " + p.returncode)
return output
我在行 output, error = p.communicate()
:
中得到一个 UnicodeDecodeError
Traceback (most recent call last):
File "C:\Python34\lib\threading.py", line 921, in _bootstrap_inner
self.run()
File "C:\Python34\lib\threading.py", line 869, in run
self._target(*self._args, **self._kwargs)
File "C:\Python34\lib\subprocess.py", line 1170, in _readerthread
buffer.append(fh.read())
File "C:\Python34\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 27: character maps to <undefined>
我该如何解决这个问题?
universal_newlines=true
设置导致额外的编码,这是您的错误来源。
def __executeCommand(self, command: str, input: str = None) -> str:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE)
output, error = p.communicate(input)
if (len(errors) > 0):
raise EnvironmentError("Could not generate the key: " + error)
elif (p.returncode != 0):
raise EnvironmentError("Could not generate the key. Return Value: " + p.returncode)
return output
universal_newlines=true
产生基于以下输出的编码:
python -c 'import locale; print locale.getpreferredencoding()'
Python 在预期您的输入与上述编码匹配时抛出错误,但却以不同的编码清楚地处理了一个字节。
有关 python 3.4 universal_newlines
here 的更多信息。
univeral_newlines=True
启用文本模式。子进程输出(字节)使用 locale.getpreferredencoding(False)
字符编码解码为 .
如果它不起作用,请提供 command
使用的实际 encoding
。 And/or指定错误处理程序如'ignore'
,'surrogateescape'
, etc作为errors
参数:
from subprocess import Popen, PIPE
def __executeCommand(self, command: str, input: str = None,
encoding=None, errors='strict') -> str:
text_mode = (encoding is None)
with Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE,
universal_newlines=text_mode) as p:
if input is not None and not text_mode:
input = input.encode(encoding, errors) # convert to bytes
output, err = p.communicate(input)
if err or p.returncode != 0:
raise EnvironmentError("Could not generate the key. "
"Error: {}, Return Value: {}".format(
ascii(err), p.returncode))
return output if text_mode else output.decode(encoding, errors)
如果您使用的是 Python 3.6 或更高版本,您可以通过更改此行来修复错误:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, universal_newlines=True)
对此:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, encoding="utf-8", universal_newlines=True)
我在上面使用了 UTF-8,但您可以将其替换为您需要的任何编码。
我的一个用户是 运行 我的代码 运行 tasklist
命令 Windows。要修复此错误,我必须使用 iso-8859-2 编码。
p = sub.Popen(cmd, stdout=sub.PIPE, stdin=sub.PIPE, stderr=sub.PIPE,
text=True, encoding='iso-8859-2')
我有这个代码:
def __executeCommand(self, command: str, input: str = None) -> str:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, universal_newlines=True)
p.stdin.write(input)
output, error = p.communicate()
if (len(errors) > 0):
raise EnvironmentError("Could not generate the key: " + error)
elif (p.returncode != 0):
raise EnvironmentError("Could not generate the key. Return Value: " + p.returncode)
return output
我在行 output, error = p.communicate()
:
Traceback (most recent call last):
File "C:\Python34\lib\threading.py", line 921, in _bootstrap_inner
self.run()
File "C:\Python34\lib\threading.py", line 869, in run
self._target(*self._args, **self._kwargs)
File "C:\Python34\lib\subprocess.py", line 1170, in _readerthread
buffer.append(fh.read())
File "C:\Python34\lib\encodings\cp1252.py", line 23, in decode
return codecs.charmap_decode(input,self.errors,decoding_table)[0]
UnicodeDecodeError: 'charmap' codec can't decode byte 0x81 in position 27: character maps to <undefined>
我该如何解决这个问题?
universal_newlines=true
设置导致额外的编码,这是您的错误来源。
def __executeCommand(self, command: str, input: str = None) -> str:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE)
output, error = p.communicate(input)
if (len(errors) > 0):
raise EnvironmentError("Could not generate the key: " + error)
elif (p.returncode != 0):
raise EnvironmentError("Could not generate the key. Return Value: " + p.returncode)
return output
universal_newlines=true
产生基于以下输出的编码:
python -c 'import locale; print locale.getpreferredencoding()'
Python 在预期您的输入与上述编码匹配时抛出错误,但却以不同的编码清楚地处理了一个字节。
有关 python 3.4 universal_newlines
here 的更多信息。
univeral_newlines=True
启用文本模式。子进程输出(字节)使用 locale.getpreferredencoding(False)
字符编码解码为
如果它不起作用,请提供 command
使用的实际 encoding
。 And/or指定错误处理程序如'ignore'
,'surrogateescape'
, etc作为errors
参数:
from subprocess import Popen, PIPE
def __executeCommand(self, command: str, input: str = None,
encoding=None, errors='strict') -> str:
text_mode = (encoding is None)
with Popen(command, stdout=PIPE, stderr=PIPE, stdin=PIPE,
universal_newlines=text_mode) as p:
if input is not None and not text_mode:
input = input.encode(encoding, errors) # convert to bytes
output, err = p.communicate(input)
if err or p.returncode != 0:
raise EnvironmentError("Could not generate the key. "
"Error: {}, Return Value: {}".format(
ascii(err), p.returncode))
return output if text_mode else output.decode(encoding, errors)
如果您使用的是 Python 3.6 或更高版本,您可以通过更改此行来修复错误:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, universal_newlines=True)
对此:
p = sub.Popen(command, stdout=sub.PIPE, stderr=sub.PIPE, stdin=sub.PIPE, encoding="utf-8", universal_newlines=True)
我在上面使用了 UTF-8,但您可以将其替换为您需要的任何编码。
我的一个用户是 运行 我的代码 运行 tasklist
命令 Windows。要修复此错误,我必须使用 iso-8859-2 编码。
p = sub.Popen(cmd, stdout=sub.PIPE, stdin=sub.PIPE, stderr=sub.PIPE,
text=True, encoding='iso-8859-2')