为啥打印的 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::Pythoncode 无法打印到重定向的输出?

【问题讨论】:

如果你尝试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 函数重定向失败?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的函数在 python 中没有打印 [重复]

为啥我的 C 函数不打印任何内容?

为啥我的 Python 函数打印一个值但返回 None? [关闭]

为啥在烧瓶中没有调用函数时会有一些打印? [复制]

为啥二维矩阵 U 不在主函数内打印?

为啥 R 对象不在函数或“for”循环中打印?