web-dev-qa-db-ja.com

サブプロセスPopenと呼び出しの違いは何ですか(どのように使用できますか)?

Pythonから外部プログラムを呼び出したい。そのためにPopen()call()の両方を使用しました。

2つの違いは何ですか?

私の具体的な目標は、Pythonから次のコマンドを実行することです。リダイレクトの仕組みがわかりません。

./my_script.sh > output

ドキュメント を読んで、call()は便利な関数またはショートカット関数であると言っています。 call()の代わりにPopen()を使用することにより、パワーを失いますか?

161
varunl

リダイレクトを行うには2つの方法があります。両方ともsubprocess.Popenまたはsubprocess.callに適用されます。

  1. キーワード引数Shell = Trueまたはexecutable = /path/to/the/Shellを設定し、そこにあるとおりにコマンドを指定します。

  2. 出力をファイルにリダイレクトしているだけなので、キーワード引数を設定します

    stdout = an_open_writeable_file_object
    

    ここで、オブジェクトはoutputファイルを指します。

subprocess.Popensubprocess.call より一般的です。

Popenはブロックしないため、実行中のプロセスと対話したり、Pythonプログラムで他のことを続行したりできます。 Popenの呼び出しは、Popenオブジェクトを返します。

calldoesブロック。 Popenコンストラクターと同じ引数をすべてサポートしているため、プロセスの出力や環境変数などを設定できますが、スクリプトはプログラムが完了するまで待機し、callはコードを返しますプロセスの終了ステータスを表します。

returncode = call(*args, **kwargs) 

基本的に呼び出しと同じです

returncode = Popen(*args, **kwargs).wait()

callは単なる便利な関数です。 CPythonでの実装は subprocess.py にあります:

def call(*popenargs, timeout=None, **kwargs):
    """Run command with arguments.  Wait for command to complete or
    timeout, then return the returncode attribute.

    The arguments are the same as for the Popen constructor.  Example:

    retcode = call(["ls", "-l"])
    """
    with Popen(*popenargs, **kwargs) as p:
        try:
            return p.wait(timeout=timeout)
        except:
            p.kill()
            p.wait()
            raise

ご覧のとおり、これはPopenを囲む薄いラッパーです。

241
agf