我想要实时访问解释器的输入、错误和标准输出。最好将这些信息写入文件,以便在输入每个解释器命令后轮询文件以查看更改。例如,给定一个解释器会话:
>>> 5 * 7
35
>>> print("Hello, world!")
Hello, world!
>>> "Hello, world!"
'Hello, world!'
我希望在日志文件中看到以下内容:
> 5 * 7
35
> print("Hello, world!")
Hello, world!
> "Hello, world!"
'Hello, world!'
格式并不重要。重要的是我能够搜索文件以触发会话期间的交互事件。
到目前为止,我尝试过的方法是:
Python的code
模块允许我创建一个InteractiveConsole
对象,该对象的raw_input
方法可以重新定义为记录到一个文件中,如下所示:
import code
class LoggedConsole(code.InteractiveConsole):
def __init__(self, locals):
super(LoggedConsole, self).__init__(locals)
self.file = open('consolelog.dat', 'a')
def __del__(self):
self.file.close()
def raw_input(self, prompt=""):
data = input(prompt)
self.file.write(data+'\n')
return data
此外,InteractiveConsole
使用内置的 write
方法记录错误,我可以重新定义它为:
def write(self, data):
sys.stderr.write(data)
self.file.write(data+'\n')
我还学习了以下代码片段,它将记录所有的标准输出:
class Tee(object):
def __init__(self):
self.file = open('consolelog.dat', 'a')
self.stdout = sys.stdout
def __del__(self):
sys.stdout = self.stdout
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)
sys.stdout = Tee()
我(失败的)尝试将所有这些内容汇总起来,是创建一个LoggedConsole
对象,并将其传递给本地的Tee
。
console = LoggedConsole(locals={sys.stdout:LoggedExec()})
console.interact()
(我之前从未传递过本地变量,所以也许我在这里做得不正确,但我没有收到错误。)
无论如何,这将打开一个新的交互式控制台,并记录(关闭后)所有输入和错误,但不会输出。我已经苦思冥想了一段时间,感觉自己很接近,但也许还不够。
此外,在会话期间是否有一种方法可以实现所有这些操作?目前所有日志记录都在会话关闭后进行。
谢谢您的时间,对于这堵文字墙表示抱歉。
编辑: 出于可移植性考虑,我希望能够在标准Python解释器中完成此操作。
编辑2: Jaime的代码片段非常适合记录我需要的一切。不过,有没有办法让它实时执行,而不是等待会话结束?
编辑3: 找到了:)最终、可工作的代码片段:
import code
import sys
class Tee(object):
def __init__(self, log_fname, mode='a'):
self.log = open(log_fname, mode)
def __del__(self):
# Restore sin, so, se
sys.stdout = sys.__stdout__
sys.stdir = sys.__stdin__
sys.stderr = sys.__stderr__
self.log.close()
def write(self, data):
self.log.write(data)
self.log.flush()
sys.__stdout__.write(data)
sys.__stdout__.flush()
def readline(self):
s = sys.__stdin__.readline()
sys.__stdin__.flush()
self.log.write(s)
self.log.flush()
return s
def flush(foo):
return
sys.stdout = sys.stderr = sys.stdin = Tee('consolelog.dat', 'w')
console = code.InteractiveConsole()
console.interact()
ipython notebook
是交互式工作流程的一个很好的补充,如果你还没有看到的话。 - Kos