Сведения о вопросе

DED

13:41, 9th August, 2020

Теги

python   windows   cmd    

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

Просмотров: 430   Ответов: 5

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

Если да, то в какую библиотеку(y|ies) мне следует заглянуть?



  Сведения об ответе

SILA

08:13, 11th August, 2020

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

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 для получения информации об управлении процессом. Для связи каналы process.stdin и process.stdout считаются стандартными файловыми объектами .

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

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

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

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


  Сведения об ответе

padenie

22:03, 4th August, 2020

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

1.  Is это возможно, чтобы захватить выход Python переводчик с Python сценарий?

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

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"

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

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 в тот же или другой файл. Также смотрите этот ответ на соответствующий вопрос.


  Сведения об ответе

davran

04:05, 20th August, 2020

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

Можно заменить 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 (где обычно печатается print to)
  • первая строка, которая записывается в stderr, начинается с 'It'
  • следующие две строки-это те, которые были собраны в объекте StringIO

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

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


  Сведения об ответе

KOMP

18:40, 4th August, 2020

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


  Сведения об ответе

dump

00:46, 21st August, 2020

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

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

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

somescript.py | your-capture-program-here

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

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться