web-dev-qa-db-ja.com

サブプロセスモジュールのcheck_callcheck_output呼び出しとPopenメソッドの実際的な違いは何ですか?

正直なところ、ヘルプページで何が起こっているのか、それが何を意味するのか(定義されていません)を実際に解釈するための「ゼロ以外」ステータスの用語を理解していません。 pythonを使用して、これらのプロセスが実行される他のスクリプトを呼び出す例をいくつか示します。

subprocess.call subprocess.check_output subprocess.popen

本当に違うの?これらのいずれかをいつ使用しますか。また、これらの方法の明確な詳細は何ですか。単純なOS呼び出しが必要な場合は、代わりにos.systemを使用する必要がありますか?

10
Tom

主な違いは、 popennon-blocking関数ですが(つまり、呼び出しが終了するのを待たずにプログラムを実行する)、 call_check_output_ の両方がブロックされます

他の違いは、彼らが返すものにあります:

メソッド call および _check_output_ は、実際には、-のblockingラッパーです。 popen 、_Popen object_を使用。たとえば、Popen.returncode()を呼び出すことで、 returncode 属性を取得できます。

15
otorrillas

@otorrillasの答えをいくつかの例で拡張します。

成功するかどうかだけを気にする短いスクリプトがあり*、今すぐ実行して結果を待ちたいとします。たとえば、単一のpingをリモートマシンに送信するとします。 callはあなたのためのものです:

res = call(['ping', '127.0.0.1', '-c', '1', '-W', '1'])
# res is 0 if the ping succeeded, non-zero if it failed. 

ここで、成功すると想定したいコマンドがあり、何かに使用したい出力を提供するとします。 check_output あなたのためです。おそらくSubversionコマンド:

svn_output = check_output(['svn', 'info', path_to_my_working_copy])
# svn_output now contains the svn info output. If it failed, an 
# exception is thrown which more easily allows you to give 
# responsibility of that failure to whoever passed us the wrong 
# path_to_my_working_copy.

一般に、ユースケースがこれらのカテゴリのいずれかに単純に当てはまらない場合は、おそらくPopenを使用することになります。

簡単な使用例の1つは、開始したいデーモンプロセスがあるが、pythonプロセスと並行して実行する場合です。ここでPopenを使用します:

my_proc = Popen(['my-daemon'])

# We're going to go and do something else now, but want to make sure
# my_proc dies when we do.
import atexit
atexit.register(my_proc.kill)

NB:Popen rawを使用する場合は、おそらくatexitを使用して、プロセスを終了する必要があります。私は説明しました。

*「ゼロ以外」の終了ステータスは、プロセスが失敗したことを意味します。 Tolstoy に起因する有名なコンピュータサイエンスの引用は、「幸せなプロセスはすべて同じです。すべての不幸なプロセスは独自の方法で不幸です」、つまり、プロセスが幸せになる唯一の方法は0を返すことです。他のすべては不幸ですが、不幸になる方法はたくさんあります。

15
daphtdazz