我在此网站上发现了一个问题,向我展示了如何从Perl调用Python脚本。我目前正在使用以下代码行来实现此目的:
pipe = subprocess.Popen(["perl", "./Perl_Script.pl", param], stdout=subprocess.PIPE)
result = pipe.stdout.read()
这很有效,但唯一的问题是Perl脚本需要几分钟才能运行。在Perl脚本的末尾,我使用一个简单的 print 语句来打印我需要返回Python的值,它将被设置为Python中的 result 变量。
有没有办法可以每隔几秒在我的Perl脚本中包含更多的print语句,这些语句可以连续返回Python(而不是等待几分钟并在最后返回一个长列表)?
最终,我正在做的是使用Perl脚本获取数据点,然后我将其发送回Python以绘制眼图。在Perl脚本完成运行时,我不想等待几分钟来绘制眼图,而是希望将数据段连续地返回到Python,允许我的绘图每隔几秒更新一次。
答案 0 :(得分:2)
默认的UNIX stdio缓冲区至少为8k。如果你的写入量少于8k,那么在刷新缓冲区之前,你最终会等到程序结束。
告诉Perl程序停止缓冲输出,并且可能告诉python不要通过管道缓冲输入。
$| = 1;
在您的Perl程序中取消缓冲STDOUT。
答案 1 :(得分:1)
pipe.stdout.read()尝试读取整个流,因此它将阻塞直到perl完成。 试试这个:
line=' '
while line:
line = pipe.stdout.readline()
print line,
答案 2 :(得分: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.html和http://perldoc.perl.org/perlvar.html。