Python 日志记录不是';t工作不正常
因此,我正在尝试编写一个装饰器,它将记录标准输出,同时打印它。整个要点是分叉输出,以便它在控制台中显示并记录。这就是我到目前为止所做的:Python 日志记录不是';t工作不正常,python,decorator,output-redirect,Python,Decorator,Output Redirect,因此,我正在尝试编写一个装饰器,它将记录标准输出,同时打印它。整个要点是分叉输出,以便它在控制台中显示并记录。这就是我到目前为止所做的: from time import time import tempfile import sys import datetime def printUsingTempFile(f): def wrapper(*a, **ka): with open('sysLog.txt', 'a') as logFile:
from time import time
import tempfile
import sys
import datetime
def printUsingTempFile(f):
def wrapper(*a, **ka):
with open('sysLog.txt', 'a') as logFile:
with tempfile.NamedTemporaryFile() as f:
sys.stdout = f
sys.stderr = f
retVal = f(*a, **ka)
f.flush(); f.seek(0); logFile.write('\n'.join(f.readlines()))
f.flush(); f.seek(0); sys.__stdout__.write('\n'.join(f.readlines()))
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
return retVal
return wrapper
if __name__ == '__main__':
@printUsingTempFile
def someFunc(abc='Hello!!!'):
'''
This is the docstring of the someFunc function.
'''
print abc
return 1
someFunc('Print something here')
我是这样运行的:
In [18]: !python utility.py
因为如果我使用run
函数运行,愚蠢的iPython窗口将关闭
我在目录中得到一个名为“”sysLog.txt“
”的新文件,但它是空的。而且在任何地方都看不到输出。没有错误或任何东西。只是没有什么!这让我有点沮丧。不确定如何调试此代码:(
编辑:
我意识到我没有寻找两次,所以我更新了代码。我尝试了以下代码:
def printUsingTempFile1():
with open('sysLog.txt', 'a') as logFile:
with tempfile.NamedTemporaryFile() as f:
sys.stdout = f
sys.stderr = f
print 'This is something ...'
f.flush(); f.seek(0); logFile.write('\n'.join(f.readlines()))
f.flush(); f.seek(0); sys.__stdout__.write('\n'.join(f.readlines()))
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
这个函数似乎工作正常。为什么要使用
f
作为传递给装饰器的函数名以及临时文件名?我假设对f(*a,**ka)的调用
errors out,由于您已将错误流重定向到临时文件,因此它会在控制台上关闭,而不会写入任何内容,因此也不会写入任何内容
调试此类情况的一个技巧是,开始逐个剥离不起作用的代码片段,并将其降至最低限度,然后再继续努力,直到它开始失败。:)
编辑
我还建议您在lint工具下运行代码,以捕获类似的问题。例如,下面张贴的代码:
''' This is a test module '''
import tempfile
import sys
def print_tmp_file(arg):
''' Print out the things using temp file '''
def wrapper(*a, **ka):
''' Wrapper function '''
with open('sysLog.txt', 'a') as log_file:
with tempfile.NamedTemporaryFile() as arg:
sys.stdout = arg
sys.stderr = arg
ret_val = arg(*a, **ka)
arg.flush()
arg.seek(0)
log_file.write('\n'.join(arg.readlines()))
arg.flush()
arg.seek(0)
sys.__stdout__.write('\n'.join(arg.readlines()))
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
return ret_val
return wrapper
if __name__ == '__main__':
@print_tmp_file
def some_func(abc='Hello!!!'):
''' This is the docstring of the someFunc function. '''
print abc
return 1
some_func('Print something here')
在上述代码上运行pylint
,会发出以下警告:
W:6,19:未使用的参数“arg”(未使用的参数)
这清楚地表明出现了问题。与其写入文件并从中读取,不如通过创建自己的
LoggingWriter
来反转此过程,其中write(self,value)
方法将写入原始stdout
和记录器。现在正在工作。多亏了Sanjay。重点仍然是,写入文件并读回是相当浪费资源的;)@沃尔夫,我想我明白你的意思了。很有趣。我也试试看。谢谢您可能还想研究使用python日志模块,在该模块中,您可以将其配置为登录到控制台、文件以及更多内容。它是由装饰者包装的函数。使用def printing usingtempfile(arg):
时,行retVal=f(*a,**ka)
应更改为retVal=arg(*a,**ka)
。这是个错误。这样,无论提供的函数打印到文件中的内容是什么,都会被记录下来。然而,最后我认为我真的需要研究一下索拉姆兹的苏格斯顿。我本来可以省下很多麻烦的。