为啥打印的 Inline::Python 函数重定向失败?
Posted
技术标签:
【中文标题】为啥打印的 Inline::Python 函数重定向失败?【英文标题】:Why do Inline::Python functions that print fail to be redirected?为什么打印的 Inline::Python 函数重定向失败? 【发布时间】:2021-10-09 20:43:11 【问题描述】:这是解决我的问题的最简单的重现方法:
#!/usr/bin/env perl
use 5.16.3;
say "Got back ", test_print();
use Inline Python => <<'END_OF_PYTHON_CODE';
def test_print() -> int:
print("In the python test print")
return 32
END_OF_PYTHON_CODE
简单运行时:
$ perl small.pl
In the python test print
Got back 32
但是当重定向时:
$ perl small.pl | tee foo
Got back 32
$ cat foo
Got back 32
我做错了什么导致Inline::Python
code 无法打印到重定向的输出?
【问题讨论】:
如果你尝试print('...', file=sys.stderr)
会发生什么? (或sys.stdout
以外的任何内容)。一个奇怪的猜测是,如果它是终端,它只会让内联代码写入标准输出;这将是一种排除这种可能性的方法。
如果我像这样预先调用unbuffer,它对我有用:unbuffer perl small.pl | tee foo
Re "如果我预先调用 unbuffer 对我有用",所以 python 不会刷新它的缓冲区。听起来 Python 没有正确退出?
Reported
谢谢池上。我需要以 $ 将程序从 Perl 转换为 Python,这将是日志记录的问题。
【参考方案1】:
Py_Finalize()
未被调用以正确破坏 Python 解释器。
幸运的是,该模块将此函数公开为py_finalize
,允许我们自己调用它。将以下内容添加到您的程序中:
END Inline::Python::py_finalize();
演示:
use feature qw( say );
use Inline Python => <<'END_OF_PYTHON_CODE';
def test_print() -> int:
print("In the python test print")
return 32
END_OF_PYTHON_CODE
END Inline::Python::py_finalize() if $ARGV[0];
say "Got back ", test_print();
$ perl a.pl 0
In the python test print
Got back 32
$ perl a.pl 0 | cat
Got back 32
$ perl a.pl 1
In the python test print
Got back 32
$ perl a.pl 1 | cat
In the python test print
Got back 32
【讨论】:
【参考方案2】:完成的事情是:
BEGIN
# Unbuffer Python's output
$ENVPYTHONUNBUFFERED=1;
# Unbuffer Perl's output
select((select(STDOUT), $|=1)[0]);
select((select(STDERR), $|=1)[0]);
...
END
# Shut down the Python interpreter.
Inline::Python::py_finalize();
您必须还取消缓冲 Perl 的输出。感谢 ikegami 在一篇现已删除的帖子中对此发表了评论,并提醒了我 py_finalize()
。
【讨论】:
已更新。谢谢。以上是关于为啥打印的 Inline::Python 函数重定向失败?的主要内容,如果未能解决你的问题,请参考以下文章