4

我在这个网站上发现了一个问题,它向我展示了如何从Python调用Perl脚本。我目前正在使用以下代码行来实现这一点:

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

这很完美,但唯一的问题是 Perl 脚本需要几分钟才能运行。在 Perl 脚本的末尾,我使用一个简单的print语句来打印我需要返回给 Python 的值,该值被设置为 Python 中的结果变量。

有没有一种方法可以每隔几秒钟在我的 Perl 脚本中包含更多的打印语句,这些语句可以连续返回到 Python(而不是等待几分钟并在最后返回一个长列表)?

最终,我正在做的是使用 Perl 脚本获取数据点,然后我将这些数据点发送回 Python 以绘制眼图。当 Perl 脚本运行完毕后,我不想等待几分钟来绘制眼图,而是希望将数据片段连续返回给 Python,让我的绘图每隔几秒钟更新一次。

4

3 回答 3

2

默认的 UNIX 标准输出缓冲区至少为 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 空间中一次读取一行,并从 Perl 一次发出一行。第一个可以通过像这样的循环来完成

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

阻塞直到从附加进程接收readline到一行文本(或EOF),然后为您提供它读取的数据。只要每个数据块都在自己的行上,那应该可以。

但是,如果您在不修改 Perl 脚本的情况下运行此代码,那么很长一段时间内您都不会得到任何输出,可能要等到 Perl 脚本执行完毕。这是因为默认情况下 Perl 块缓冲区输出到管道。您可以通过更改要打印的范围内的全局变量来告诉它更频繁地刷新缓冲区:

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

请参阅http://perl.plover.com/FAQs/Buffering.htmlhttp://perldoc.perl.org/perlvar.html

于 2012-11-29T22:48:33.587 回答