4

このサイトで、 PythonからPerlスクリプトを呼び出す方法を示す質問を見つけました。私は現在、これを実現するために次のコード行を使用しています。

pipe = subprocess.Popen(["perl", "./Perl_Script.pl", param], stdout=subprocess.PIPE)
result = pipe.stdout.read()

これは完全に機能しますが、唯一の問題は、Perlスクリプトの実行に数分かかることです。Perlスクリプトの最後で、単純なprintステートメントを使用して、Pythonに戻す必要のある値を出力します。これは、Pythonの結果変数に設定されます。

数秒待って最後に長いリストを返す代わりに、Pythonに継続的に返すことができる数秒ごとにPerlスクリプトにさらに多くのprintステートメントを含めることができる方法はありますか?

最終的に、私が行っているのは、Perlスクリプトを使用してデータポイントを取得し、それをPythonに返送してアイダイアグラムをプロットすることです。Perlスクリプトの実行が終了したときにアイダイアグラムをプロットするのに数分待つのではなく、データのセグメントをPythonに継続的に返し、プロットを数秒ごとに更新できるようにします。

4

3 に答える 3

2

デフォルトのUNIXstdioバッファは少なくとも8kです。書き込みが8k未満の場合は、プログラムが終了するまで待機してから、バッファーがフラッシュされます。

Perlプログラムに出力のバッファリングを停止するように指示し、おそらくPythonにパイプを介して入力をバッファリングしないように指示します。

$| = 1;

PerlプログラムでSTDOUTのバッファを解除します。

于 2012-11-29T21:27:33.763 に答える
1

pipe.stdout.read()はストリーム全体を読み取ろうとするため、perlが終了するまでブロックされます。これを試して:

line=' '
while line:
    line = pipe.stdout.readline()
    print line,
于 2012-11-29T21:29:41.360 に答える
1

Pythonスペースで一度に1行を読み取ることと、Perlから一度に1行を出力することの2つの部分が必要です。最初のものは、次のようなループで実行できます。

while True:
  result = pipe.stdout.readline()
  if not result:
    break
  # do something with result

添付されたプロセスから1行のreadlineテキスト(またはEOF)が受信されるまでブロックし、読み取ったデータを提供します。データの各チャンクが独自の行にある限り、それは機能するはずです。

ただし、Perlスクリプトを変更せずにこのコードを実行すると、Perlスクリプトの実行が終了するまで、かなりの期間、出力が得られません。これは、Perlブロックバッファがデフォルトでパイプに出力されるためです。印刷するスコープのグローバル変数を変更することで、バッファーをより頻繁にフラッシュするように指示できます。

use English qw(-no_match_vars);
local $OUTPUT_AUTOFLUSH = 1;
print ...;

http://perl.plover.com/FAQs/Buffering.htmlおよびhttp://perldoc.perl.org/perlvar.htmlを参照してください。

于 2012-11-29T22:48:33.587 に答える