subproc.py
import osimport sys
import locale
import subprocess
from distutils.ccompiler import new_compiler
ccompiler = new_compiler()
ccompiler.initialize()
cc = subprocess.check_output(f"{ccompiler.cc}", stderr=subprocess.STDOUT, shell=True)
encoding = os.device_encoding(sys.stdout.fileno()) or locale.getpreferredencoding()
print("Encoding:", encoding)
compiler_name = cc.decode(encoding).partition("\n")[0].strip()
print("Compiler name:", compiler_name)
При непосредственном вызове, т. Е. Запуск subprocess.py напрямую все работает нормально. Имя компилятора правильно идентифицировано как «Microsoft (R) C/C ++-OptimierOUngScompiler версия 19.42.34433 Für x64 ' (я думаю, что является источником проблемы)
Однако, когда я называю его с помощью subprocess.popen (), OS.Device_Encoding возвращает нет вместо CP850 , в результате чего программа по умолчанию в кодирование Windows CP1252 , который затем вызывает cc.decode (кодирование) для повышения "UnicodeDecodeerror: 'CHARMAP' CODEC не может декодировать byte 0x81 в положении 62: Карты символов в " . < /p>
Вот как я запускаю подпроцесс: < /p>
call_subprocess.py
import subprocesssubprocess.Popen(
[
"python",
"C:/path/to/subproc.py",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
Насколько я понимаю, OS.Device_encoding (sys.stdout.fileno ()) не может найти кодирование, поскольку подпроцесс работает в фоновом режиме без терминала. Кроме того, Windows всегда будет предоставлять CP1252 при запросе с помощью locale.getPreferredEncoding () .
Поскольку я не могу редактировать код во внешнем пакете, есть ли способ Чтобы вызвать подпроцесс, чтобы заставить любую из этих команд возвращать варианты CP850 ? br /> [*] Явно установите кодирование в Popen:
subprocess.Popen(
...
text=True,
encoding="cp850",
)
< /code>
< /li>
Явно установите pythonioEncoding < /code> в субпроцессовой среде:
environ = os.environ.copy()
environ['PYTHONIOENCODING'] = 'utf-8'
...
subprocess.Popen(
...
env=environ,
encoding='utf-8',
)
[*] Использовать subprocess.run () вместо subprocess.popen ()
[*] Различные комбинации решений, выше. > Subprocess использует неправильную кодировку в Windows < /li>
Ошибка кодирования, работающая в подпроцессе с захваченным выходом < /li>
Изменение предпочтительного локали для самого компьютера: Панель управления> Часы и регион> Регион> Административный> Локаль системы изменения> Проверьте бета -версию: Использовать Unicode UTF -8> перезагрузка -> работает, но не желает, так как код должен выполняться на разных машинах без индивидуальной настройки каждый раз.
Поскольку в моем случае подпроцесс был довольно изолирован от другого кода и его собственную функцию запуска, я использовал следующие строки перед первым импортом локали, чтобы переопределить возвратное значение locale.getDefaultlocale () ( Источник): < /li>
< /ul>
# Override locale.getdefaultlocale() for the subprocess.
# This is necessary to avoid issues with the default locale on Windows.
# It might cause issues on computers not in western countries, that do not use cp850.
import _locale
_locale._getdefaultlocale = lambda *args: ["en_US", "cp850"]
Подробнее здесь: https://stackoverflow.com/questions/793 ... ding-error