3

コードは次のとおりです。

from subprocess import Popen, PIPE


p1 = Popen("command1", stdout = PIPE)
p2 = Popen("command2", stdin = p1.stdout, stdout = PIPE)
result_a = p2.communicate()[0]

p1_again = Popen("command1", stdout = PIPE)
p3 = Popen("command3", stdin = p1_again.stdout, stdout = PIPE)
result_b = p3.communicate()[0]

with open("test") as tf:
    p1_again_again = Popen("command1", stdout = tf)
    p1_again_again.communicate()

悪い部分は次のとおりです。

一度使用すると、そのオブジェクトのは二度と使用できないcommand1ため、は3回実行されました。の中間結果を再利用する方法があるかどうか疑問に思っていました。commnnicatestdoutPopenPIPE

これらのコードをより良くする方法(パフォーマンスを向上させ、コードの行を減らす)について誰かがアイデアを持っていますか?ありがとう!

4

2 に答える 2

3

これが実用的な解決策です。cmd1、cmd2、cmd3のサンプルコマンドを配置して、実行できるようにしました。最初のコマンドからの出力を取得し、一方のコマンドで大文字にし、もう一方のコマンドで小文字にします。

コード

from subprocess import Popen, PIPE, check_output
from tempfile import TemporaryFile

cmd1 = ['echo', 'Hi']
cmd2 = ['tr', '[:lower:]', '[:upper:]']
cmd3 = ['tr', '[:upper:]', '[:lower:]']

with TemporaryFile() as f:
    p = Popen(cmd1, stdout=f)
    ret_code = p.wait()
    f.flush()
    f.seek(0)
    out2 = Popen(cmd2, stdin=f, stdout=PIPE).stdout.read()
    f.seek(0)
    out3 = Popen(cmd3, stdin=f, stdout=PIPE).stdout.read()
    print out2, out3

出力

HI
hi

ソリューションで注意すべき点のいくつか。一時ファイルモジュールは、一時ファイルを操作する必要がある場合に常に最適な方法です。withステートメントが終了すると、withブロック全体でio例外がスローされた場合でも、一時ファイルがクリーンアップとして自動的に削除されます。cmd1は1回実行され、一時ファイルに出力されます。wait()メソッドを呼び出してすべての実行が完了したことを確認してから、毎回seek(0)を実行して、fでread()メソッドを呼び出すと元に戻ります。ファイルの先頭。参考として、 subprocess.Popenからfileにstdoutを保存するという質問は、ソリューションの最初の部分を取得するのに役立ちました。

于 2012-11-22T03:43:23.703 に答える