Как подпроцесс решает, какую кодировку записать в файловые объекты, которые принимают только str - PullRequest
4 голосов
/ 12 апреля 2019

Я нашел следующее поведение весьма запутанным:

Python 3.7.2 (default, Feb 12 2019, 08:15:36) 
[Clang 10.0.0 (clang-1000.11.45.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import subprocess
>>> import sys
>>> sys.stdout.write(b'')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: write() argument must be str, not bytes
>>> subprocess.run('echo', stdout=sys.stdout)

CompletedProcess(args='echo', returncode=0)

sys.stdout не принимает двоичные файлы. Я не указал кодировку для моего subprocess вызова, это означает, что он должен быть потоковым двоичным. Как подпроцесс узнал, что в этом случае не нужно передавать двоичные данные файлового объекта?

1 Ответ

3 голосов
/ 12 апреля 2019

Вы неправильно понимаете, как работают подпроцессы.Подпроцесс не взаимодействует с объектом sys.stdout - этот объект существует только в python и только в вашем процессе.

Чтобы понять, что на самом деле происходит, вам сначала нужно знать, какОС обрабатывает IO.На уровне операционной системы каждому открытому файлу (или каналу) присваивается идентификатор - он называется дескриптор файла .Например, дескриптор для stdout обычно является числом 1:

>>> sys.stdout.fileno()
1

Когда вы запускаете подпроцесс, только этот дескриптор файла передается подпроцессу.Подпроцесс не имеет доступ к объекту sys.stdout.Все, что может сделать подпроцесс, - это записать байты в обработчик файла, который он получил.(На уровне ОС есть только байты, без текста.) Вы не можете заставить подпроцесс использовать определенную кодировку.

Когда вы передаете аргумент encoding в subprocess.run, эта кодировка толькоиспользуется для кодирования текста, отправляемого в подпроцесс или получаемого из подпроцесса.Он не влияет на сам подпроцесс, он влияет только на то, как ваш процесс взаимодействует с подпроцессом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...