Как захватить интерпретатор Python и / или CMD.Вывод EXE из скрипта Python?

  1. можно ли захватить вывод интерпретатора Python из скрипта Python?
  2. можно ли захватить выходные данные Windows CMD из скрипта Python?

если да, то в какую библиотеку(ы|ы) я должен заглянуть?

5 ответов


Если вы говорите о интерпретаторе python или CMD.exe, который является "родителем" вашего скрипта, тогда нет, это невозможно. В каждой POSIX-подобной системе (теперь вы используете Windows, кажется, и это может иметь некоторую причуду, о которой я не знаю, YMMV) каждый процесс имеет три потока, стандартный ввод, стандартный вывод и стандартную ошибку. Bu по умолчанию (при запуске в консоли) они направлены на консоль, но перенаправление возможно с помощью обозначения канала:

python script_a.py | python script_b.py

этот связывает стандартный выходной поток скрипта a со стандартным входным потоком скрипта B. Стандартная ошибка по-прежнему идет в консоль в этом примере. См. статью стандартные потоки на Википедии.

Если вы говорите о дочернем процессе, вы можете запустить его с python так (stdin также является опцией, если вы хотите двустороннюю связь):

import subprocess
# Of course you can open things other than python here :)
process = subprocess.Popen(["python", "main.py"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
x = process.stderr.readline()
y = process.stdout.readline()
process.wait()

смотрите Python подпроцесс модуль для информации об управлении процессом. Для общение, процесс.stdin и процесс.трубы stdout считаются стандартными объекты.

для пользы с трубами, читая от стандартного входного сигнала как lassevk предложил тебе сделать что-то вроде этого:

import sys
x = sys.stderr.readline()
y = sys.stdin.readline()

sys.stdin и sys.stdout-это стандартные файловые объекты, как указано выше, определенные в sys модуль. Вы также можете взглянуть на труб модуль.

чтение данных с readline () как и в моем примере, является довольно наивным способом получения данных. Если вывод не является линейно-ориентированным или неопределенным, вы, вероятно, хотите посмотреть в опрос, который к сожалению не работает в Windows, но я уверен, что есть какая-то альтернатива есть.


Я думаю, что я могу указать вам хороший ответ на первую часть вашего вопроса.

1.  Можно ли захватить вывод интерпретатора Python из Python сценарий?

ответ "да", и лично мне нравится следующее, поднятое из примеров в PEP 343 -- заявление "с" документ.

from contextlib import contextmanager
import sys

@contextmanager
def stdout_redirected(new_stdout):
    saved_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout.close()
        sys.stdout = saved_stdout

и используется следующим образом:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

A приятным аспектом этого является то, что он может применяться выборочно только вокруг части выполнения сценария, а не всего его объема, и остается в силе, даже когда необработанные исключения возникают в его контексте. Если вы повторно откроете файл в режиме добавления после его первого использования, вы можете накопить результаты в один файл:

with stdout_redirected(open("filename.txt", "w")):
    print "Hello world"

print "screen only output again"

with stdout_redirected(open("filename.txt", "a")):
    print "Hello world2"

конечно, выше также может быть расширено, чтобы также перенаправить sys.stderr к тому же или другому файлу. Также смотрите это ответ в смежный вопрос.


на самом деле, вы определенно можете, и это красиво, уродливо и безумно одновременно!

вы можете заменить sys.stdout и sys.stderr с объектами StringIO, которые собирают выходные данные.

вот пример, сохраните его как evil.py:

import sys
import StringIO

s = StringIO.StringIO()

sys.stdout = s

print "hey, this isn't going to stdout at all!"
print "where is it ?"

sys.stderr.write('It actually went to a StringIO object, I will show you now:\n')
sys.stderr.write(s.getvalue())

когда вы запустите эту программу, вы увидите, что:

  • ничего не пошло в stdout (где печать обычно печатает)
  • первая строка, которая записывается в stderr, начиная с "Это"
  • следующие две строки-это те, которые были собраны в объекте StringIO

замена sys.stdout / err, как это приложение, которое называется monkeypatching. Мнения могут варьироваться независимо от того, "поддерживается" это или нет, и это определенно уродливый хак, но он спас мой бекон, пытаясь обернуть вокруг внешних вещей один или два раза.

проверено на Linux, а не Windows, но он должен работать так же хорошо. Дай мне знать, если это сработает. Окна!


вы хотите подпроцесс. Посмотрите конкретно на Popen в 17.1.1 и общайтесь в 17.1.2.


в каком контексте вы спрашиваете?

вы пытаетесь захватить вывод из программы, которую вы запускаете в командной строке?

если да, то вот как его выполнить:

somescript.py | your-capture-program-here

читать выход, просто читать из стандартного ввода.

Если, с другой стороны, вы выполняете этот скрипт или Cmd.exe или аналогичный из вашей программы, и хотите подождать, пока скрипт / программа не закончит, и захватить все его выходные данные, тогда вам нужно посмотрите на вызовы библиотеки, которые вы используете для запуска этой внешней программы, скорее всего, есть способ попросить ее дать вам способ прочитать вывод и дождаться завершения.