- PythonスクリプトからPythonインタープリターの出力をキャプチャすることは可能ですか?
- PythonスクリプトからWindowsCMDの出力をキャプチャすることは可能ですか?
もしそうなら、どのライブラリ(y | ies)を調べる必要がありますか?
スクリプトの「親」であるPythonインタープリターまたはCMD.exeについて話している場合は、いいえ、それは不可能です。すべてのPOSIXのようなシステム(現在Windowsを実行しているようですが、それは私が知らない癖があるかもしれません、YMMV)では、各プロセスに3つのストリーム、標準入力、標準出力、および標準エラーがあります。デフォルトでは(コンソールで実行している場合)、これらはコンソールに送信されますが、パイプ表記を使用してリダイレクトできます。
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パイプは標準のファイルオブジェクトと見なされます。
パイプで使用する場合、 lassevkとして標準入力から読み取ると、次のようなことを行うことが提案されます。
import sys
x = sys.stderr.readline()
y = sys.stdin.readline()
sys.stdinおよびsys.stdoutは、上記の標準ファイルオブジェクトであり、sysモジュールで定義されています。また、パイプモジュールも確認することをお勧めします。
私の例のようにreadline()を使用してデータを読み取ることは、データを取得するための非常に単純な方法です。出力が行指向または非決定論的でない場合は、残念ながらウィンドウでは機能しないポーリングを調べたいと思うかもしれませんが、そこにいくつかの代替手段があると確信しています。
あなたの質問の最初の部分に対する適切な答えを教えていただけると思います。
1. Python スクリプトから Python インタープリターの出力をキャプチャすることは可能ですか?
答えは「はい」です。個人的には、 PEP 343 -- The "with" Statement documentの例から引用した以下のものが好きです。
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"
これの優れた点は、スクリプトの実行全体ではなく、スクリプトの実行の一部だけに選択的に適用でき、そのコンテキスト内で未処理の例外が発生した場合でも有効なままになることです。ファイルを最初に使用した後に追加モードで再度開くと、結果を 1 つのファイルに蓄積できます。
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())
このプログラムを実行すると、次のことがわかります。
sys.stdout / errをこのように置き換えることは、モンキーパッチと呼ばれるもののアプリケーションです。これが「サポートされている」かどうかについては意見が異なる場合があり、間違いなく醜いハックですが、外部のものを1〜2回ラップしようとすると、ベーコンが節約されます。
WindowsではなくLinuxでテストされていますが、同様に機能するはずです。Windowsで動作するかどうか教えてください!
サブプロセスが必要です。特に17.1.1のPopenを見て、17.1.2で通信します。
どのような文脈であなたは尋ねていますか?
コマンドラインで起動したプログラムからの出力をキャプチャしようとしていますか?
もしそうなら、これはそれを実行する方法です:
somescript.py | your-capture-program-here
出力を読み取るには、標準入力から読み取るだけです。
一方、プログラム内からそのスクリプトまたはcmd.exeなどを実行していて、スクリプト/プログラムが終了するまで待機し、そのすべての出力をキャプチャする場合は、ライブラリを確認する必要があります。その外部プログラムを開始するために使用する呼び出し。ほとんどの場合、出力を読み取って完了を待つ方法を提供するように要求する方法があります。