问题描述
我正在使用一个 Python 库(用 C++ 编写),它在控制台中输出大量消息。不幸的是,该库是封闭源代码,因此无法更改其行为。我的目标是编写一个 Python 上下文处理程序,将库 C++ 输出(标准输出和标准错误)重定向到两个文件中,同时保持 Python 输出不变(显示在控制台中)。到目前为止,这是我设法完成的:
import os
import sys
from pathlib import Path
log_dir = Path('./')
class logSaver():
def __init__(self,logname):
self.logname = logname
sys.stdout.flush()
sys.stderr.flush()
if self.logname == None:
self.logpath_out = os.devnull
self.logpath_err = os.devnull
else:
self.logpath_out = log_dir / (logname + "_out.log")
self.logpath_err = log_dir / (logname + "_err.log")
self.logfile_out = os.open(self.logpath_out,os.O_WRONLY|os.O_TRUNC|os.O_CREAT)
self.logfile_err = os.open(self.logpath_err,os.O_WRONLY|os.O_TRUNC|os.O_CREAT)
def __enter__(self):
self.orig_stdout = sys.stdout # save original stdout
self.orig_stderr = sys.stderr # save original stderr
self.new_stdout = os.dup(1)
self.new_stderr = os.dup(2)
os.dup2(self.logfile_out,1)
os.dup2(self.logfile_err,2)
sys.stdout = os.fdopen(self.new_stdout,'w')
sys.stderr = os.fdopen(self.new_stderr,'w')
def __exit__(self,exc_type,exc_val,exc_tb):
sys.stdout.flush()
sys.stderr.flush()
sys.stdout = self.orig_stdout # restore original stdout
sys.stderr = self.orig_stderr # restore original stderr
os.close(self.logfile_out)
os.close(self.logfile_err)
然后使用上下文处理程序如下:
with logSaver("log_filename"):
some_cpp_and_python_code()
结果是创建了两个文件:
- log_filename_out.log
- log_filename_err.log
包含 C++ 库产生的所有输出,而 Python 产生的输出会定期显示在控制台中,不会写入日志文件。
代码工作正常,只重定向 C++ 标准输出,而 Python print()
调用保持不变,但是,由于某种原因,它只工作一次:上下文处理程序的所有后续使用都会导致破坏行为Python print()
调用的一部分,因为它们没有显示在任何地方(控制台或日志文件)。我怀疑问题可能在于原始标准输出和标准错误的错误恢复。
如何更改代码以修复此行为?
非常感谢您提前
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)