如何判断我的python程序是否(在同一程序中)向sys.stdout写入了任何内容



我正在制作一个程序,根据是否向sys.stdout写入了任何内容,该程序具有不同的控制流。我首先在Mac上制作了这个程序,我可以做这个

pos = sys.stdout.tell()
exec(some_code, globals)
if pos == sys.stdout.tell():
# ...

但事实证明,我不能在Linux上使用tell()方法,这对我来说是一个问题。在这种情况下,我如何判断sys.stdout是否被触摸?

我能想到的一个想法是为sys.stdoutsys.stdout.buffer制作一个包装类来监控所有的写入调用,尽管我不确定这是一种稳健的方法

或者我想我可以试试contextlib.redirect_stdout。但是我不知道该如何利用它。

编辑:我正在使用这个实用程序https://github.com/bombs-kim/pythonp.我尝试实现的功能是,当没有输出到stdout时,自动将exec(some_code, globals)some_code的最后一个表达式写入stdout。

在这种情况下,我如何判断sys.stdout是否被触摸?

您不能,因为stdout可能已被重定向或在管道中(通过shell中用于运行Python脚本的命令)。例如,您的用户可以通过将script.py作为script.py > /dev/null运行来将stdout重定向到/dev/null(请参见null(4)),然后您的问题就没有任何意义了。您的stdout甚至可能是一个套接字、一个fifo、一个设备等。此外,some_codeexec版本可能会更改stdout(例如,关闭它,使用os.dup2重定向它,将自己重新定义为stdoutPython对象等)

此外,您的程序甚至可能不会在终端中运行(想想crontab(5)作业,或者使用atssh运行程序)。另请参阅tty解密页面。

stdout标准流(按惯例)由调用进程(通常但不总是某些shell)设置,该进程具有fork(2)-ed和execve(2)-ed脚本。

这不是Linux特有的,而是Unix的哲学。您可能想阅读一些Unix或Linux编程书籍(如ALP)。

stdout是一个终端时,您可以使用isatty(3)来检测这种情况。但这肯定不包括所有可能的用例。

Linux有/proc/(请参阅proc(5)了解更多信息),stdout也是/dev/stdout,也就是/proc/self/fd/1,您可以在其上执行stat(2)(当然,您可以直接在STDOUT_FILENO上执行fstat,即1)。但即便如此,也无法涵盖所有可能的用例。

你有没有想过当你的程序监视自己时的情况(例如pythonp pythonp…)?

我不确定是否理解你的真正目标,但它们在我脑海中回响着莱斯定理,你的问题可能是不可决定的。

我通过在python3中封装sys.stdout.writesys.stdout.buffer.write自行解决了这个问题。

import sys
write = sys.stdout.write
write_called = [False]

def make_write_hook(old_writer, flag: list):
self = old_writer.__self__
def new_writer(value):
self.write = old_writer
flag[0] = True
old_writer(value)
return new_writer

sys.stdout.write = make_write_hook(sys.stdout.write, write_called)
sys.stdout.buffer.write = make_write_hook(
sys.stdout.buffer.write, write_called)
history = []
history.append(write_called[0])
print("hello world")
history.append(write_called[0])
print(history)
# ### output
# hello world
# [False, True]

根据我对cpython的标准库代码的观察,python的惯例是,所有对标准输出的写入都应该通过调用sys.stdout.writesys.stdout.buffer.write来完成,而不是直接调用os.fdopen(1, 'w').write之类的东西。这是我的临时结论,我希望任何比我更了解python的人都能证实这一点。谢谢大家!

相关内容

  • 没有找到相关文章

最新更新