Документация Python неофициальный перевод

popen2.md

123 строк · 12.4 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/2.7/library/popen2.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 17.5. [`popen2`](https://python-all.ru/2.7/library/popen2.html#module-popen2) – Подпроцессы с доступными потоками ввода-вывода89Устарело с версии 2.6: Этот модуль устарел. Используйте модуль [`subprocess`](https://python-all.ru/2.7/library/subprocess.html#module-subprocess). Обратите особое внимание на раздел [Замена старых функций модулем subprocess](https://python-all.ru/2.7/library/subprocess.html#subprocess-replacements).1011Этот модуль позволяет запускать процессы и подключаться к их каналам ввода/вывода/ошибок, а также получать коды возврата в Unix и Windows.1213Модуль [`subprocess`](https://python-all.ru/2.7/library/subprocess.html#module-subprocess) предоставляет более мощные средства для порождения новых процессов и получения их результатов. Использование модуля [`subprocess`](https://python-all.ru/2.7/library/subprocess.html#module-subprocess) предпочтительнее использования модуля [`popen2`](https://python-all.ru/2.7/library/popen2.html#module-popen2).1415Основной интерфейс, предоставляемый этим модулем, – это три порождающие функции. Для каждой из них, если указан *bufsize*, он задает размер буфера для каналов ввода-вывода. *mode*, если указан, должен быть строкой `'b'` или `'t'`; в Windows это необходимо для определения, должны ли файловые объекты открываться в двоичном или текстовом режиме. Значение по умолчанию для *mode*`'t'`.1617В Unix *cmd* может быть последовательностью, и в этом случае аргументы будут переданы напрямую программе без участия оболочки (как с [`os.spawnv()`](https://python-all.ru/2.7/library/os.html#os.spawnv)). Если *cmd* – строка, она будет передана оболочке (как с [`os.system()`](https://python-all.ru/2.7/library/os.html#os.system)).1819Единственный способ получить коды возврата дочерних процессов – использовать методы `poll()` или `wait()` классов [`Popen3`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen3) и [`Popen4`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen4); они доступны только в Unix. Эта информация недоступна при использовании функций [`popen2()`](https://python-all.ru/2.7/library/popen2.html#module-popen2), [`popen3()`](https://python-all.ru/2.7/library/popen2.html#popen2.popen3) и [`popen4()`](https://python-all.ru/2.7/library/popen2.html#popen2.popen4) или эквивалентных функций из модуля [`os`](https://python-all.ru/2.7/library/os.html#module-os). (Обратите внимание, что кортежи, возвращаемые функциями модуля [`os`](https://python-all.ru/2.7/library/os.html#module-os), находятся в другом порядке, чем те, что возвращаются модулем [`popen2`](https://python-all.ru/2.7/library/popen2.html#module-popen2).)2021#### `popen2.popen2(cmd[, bufsize[, mode]])`2223Выполняет *cmd* как подпроцесс. Возвращает файловые объекты `(child_stdout, child_stdin)`.2425#### `popen2.popen3(cmd[, bufsize[, mode]])`2627Выполняет *cmd* как подпроцесс. Возвращает файловые объекты `(child_stdout, child_stdin, child_stderr)`.2829#### `popen2.popen4(cmd[, bufsize[, mode]])`3031Выполняет *cmd* как подпроцесс. Возвращает файловые объекты `(child_stdout_and_stderr, child_stdin)`.3233Новое в версии 2.0.3435В Unix также доступен класс, определяющий объекты, возвращаемые порождающими функциями. Они не используются в реализации для Windows и недоступны на этой платформе.3637#### `class popen2.Popen3(cmd[, capturestderr[, bufsize]])`3839Этот класс представляет дочерний процесс. Обычно экземпляры [`Popen3`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen3) создаются с помощью порождающих функций [`popen2()`](https://python-all.ru/2.7/library/popen2.html#module-popen2) и [`popen3()`](https://python-all.ru/2.7/library/popen2.html#popen2.popen3), описанных выше.4041Если для создания объектов [`Popen3`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen3) не используются вспомогательные функции, параметр *cmd* – это команда оболочки для выполнения в подпроцессе. Флаг *capturestderr*, если true, указывает, что объект должен захватывать стандартный вывод ошибок дочернего процесса. По умолчанию false. Если указан параметр *bufsize*, он задает размер буферов ввода-вывода для дочернего процесса.4243#### `class popen2.Popen4(cmd[, bufsize])`4445Аналогично [`Popen3`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen3), но всегда захватывает стандартную ошибку в тот же файловый объект, что и стандартный вывод. Обычно создаются с помощью [`popen4()`](https://python-all.ru/2.7/library/popen2.html#popen2.popen4).4647Новое в версии 2.0.4849## 17.5.1. Объекты Popen3 и Popen45051Экземпляры классов [`Popen3`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen3) и [`Popen4`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen4) имеют следующие методы:5253#### `Popen3.poll()`5455Возвращает `-1`, если дочерний процесс еще не завершился, или его код состояния (см. [`wait()`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen3.wait)) в противном случае.5657#### `Popen3.wait()`5859Ожидает завершения дочернего процесса и возвращает его код состояния. Код состояния содержит как код возврата процесса, так и информацию о том, завершился ли он с помощью системного вызова `exit()` или был завершен сигналом. Функции для интерпретации кода состояния определены в модуле [`os`](https://python-all.ru/2.7/library/os.html#module-os); см. раздел [Управление процессами](https://python-all.ru/2.7/library/os.html#os-process) для семейства функций `W*()`.6061Также доступны следующие атрибуты:6263#### `Popen3.fromchild`6465Файловый объект, предоставляющий вывод от дочернего процесса. Для экземпляров [`Popen4`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen4) он будет предоставлять как стандартный вывод, так и стандартный поток ошибок.6667#### `Popen3.tochild`6869Файловый объект, предоставляющий ввод в дочерний процесс.7071#### `Popen3.childerr`7273Файловый объект, предоставляющий вывод ошибок от дочернего процесса, если для конструктора *capturestderr* было true, в противном случае `None`. Для экземпляров [`Popen4`](https://python-all.ru/2.7/library/popen2.html#popen2.Popen4) это всегда будет `None`.7475#### `Popen3.pid`7677PID дочернего процесса.7879## 17.5.2. Проблемы управления потоком8081При работе с любой формой межпроцессного взаимодействия необходимо тщательно продумывать управление потоком. Это относится и к файловым объектам, предоставляемым этим модулем (или эквивалентами из модуля [`os`](https://python-all.ru/2.7/library/os.html#module-os)).8283При чтении вывода из дочернего процесса, который записывает много данных в стандартную ошибку, в то время как родитель читает из стандартного вывода дочернего процесса, может возникнуть взаимоблокировка. Аналогичная ситуация может возникнуть и при других комбинациях чтения и записи. Основные факторы: один процесс записывает более `_PC_PIPE_BUF` байт в блокирующем режиме, в то время как другой процесс читает из первого, также в блокирующем режиме.8485Есть несколько способов справиться с этой ситуацией.8687Самое простое изменение приложения во многих случаях – следовать этой модели в родительском процессе:8889```python90import popen29192r, w, e = popen2.popen3('python slave.py')93e.readlines()94r.readlines()95r.close()96e.close()97w.close()98```99100с таким кодом в дочернем процессе:101102```python103import os104import sys105106# обратите внимание, что каждый из этих операторов print107# записывает одну длинную строку108109print >>sys.stderr, 400 * 'this is a test\n'110os.close(sys.stderr.fileno())111print >>sys.stdout, 400 * 'this is another test\n'112```113114Учитывайте, что `sys.stderr` необходимо закрыть после записи всех данных, иначе `readlines()` не вернёт управление. Также обратите внимание, что следует использовать [`os.close()`](https://python-all.ru/2.7/library/os.html#os.close), поскольку `sys.stderr.close()` не закроет `stderr` (в противном случае присваивание `sys.stderr` закроет его без предупреждения, и дальнейшие ошибки не будут выведены).115116Приложениям, которым требуется более общий подход, следует интегрировать ввод-вывод через каналы в свои [`select()`](https://python-all.ru/2.7/library/select.html#module-select) циклы или использовать отдельные потоки для чтения каждого из файлов, предоставленных используемой `popen*()` функцией или `Popen*` классом.117118> **См. также**119>120> **Модуль [`subprocess`](https://python-all.ru/2.7/library/subprocess.html#module-subprocess)**121>122> Модуль для порождения и управления подпроцессами.123