Popen.communicate () выбрасывает 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 

И я получаю UnicodeDecodeError в строке 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> 

Как я могу это исправить?

univeral_newlines=True включает текстовый режим. Выход субпроцесса (байты) декодируется с использованием кодировки символов locale.getpreferredencoding(False) как упоминалось в @ cdosborn .

Если он не работает, укажите фактическую encoding , используемую command . И / или указать обработчик ошибок, такой как 'ignore' , 'surrogateescape' и т. Д. Как параметр 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) 

Значение 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 здесь .