61

我试图在 python 中找到一种将脚本执行日志重定向到文件以及以stdoutpythonic 方式的方法。有什么简单的方法可以实现这一目标吗?

4

8 回答 8

63

使用日志模块(http://docs.python.org/library/logging.html):

import logging

logger = logging.getLogger('scope.name')

file_log_handler = logging.FileHandler('logfile.log')
logger.addHandler(file_log_handler)

stderr_log_handler = logging.StreamHandler()
logger.addHandler(stderr_log_handler)

# nice output format
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_log_handler.setFormatter(formatter)
stderr_log_handler.setFormatter(formatter)

logger.info('Info message')
logger.error('Error message')
于 2012-07-04T10:34:12.440 回答
55

我想出了这个[未经测试]

import sys

class Tee(object):
    def __init__(self, *files):
        self.files = files
    def write(self, obj):
        for f in self.files:
            f.write(obj)
            f.flush() # If you want the output to be visible immediately
    def flush(self) :
        for f in self.files:
            f.flush()

f = open('out.txt', 'w')
original = sys.stdout
sys.stdout = Tee(sys.stdout, f)
print "test"  # This will go to stdout and the file out.txt

#use the original
sys.stdout = original
print "This won't appear on file"  # Only on stdout
f.close()

print>>xyz在 python 中将期望write()xyz. 您可以使用您自己的自定义对象。否则,您也可以让 sys.stdout 引用您的对象,在这种情况下,即使没有>>xyz.

于 2012-07-04T08:27:26.233 回答
11

我只想在 Serpens 答案的基础上添加以下代码:

logger.setLevel('DEBUG')

这将允许您选择记录的消息级别。

例如在 Serpens 示例中,

logger.info('Info message')

不会被记录,因为它默认只记录警告及以上。

可以在此处阅读有关所用级别的更多信息

于 2014-04-13T12:46:19.153 回答
8

可能是最短的解决方案:

def printLog(*args, **kwargs):
    print(*args, **kwargs)
    with open('output.out','a') as file:
        print(*args, **kwargs, file=file)

printLog('hello world')

将“hello world”写入sys.stdout和写入output.out,其工作方式与 print() 完全相同。

注意: 请不要为 printLog 函数指定文件参数。printLog('test',file='output2.out')不支持类似的调用。

于 2017-08-28T11:32:16.830 回答
3

您应该使用logging内置此功能的库。您只需将处理程序添加到记录器以确定将输出发送到何处。

于 2012-07-04T08:43:13.797 回答
2

最简单的解决方案是重定向标准输出。在您的 python 程序文件中使用以下内容:

if __name__ == "__main__":
   sys.stdout = open('file.log', 'w')
   #sys.stdout = open('/dev/null', 'w')
   main()

任何 std 输出(例如 的输出print 'hi there')都将被重定向到,file.log或者如果您取消注释第二行,则任何输出都将被抑制。

于 2012-07-04T09:04:46.693 回答
0

创建输出文件和自定义函数:

outputFile = open('outputfile.log', 'w')

def printing(text):
    print(text)
    if outputFile:
        outputFile.write(str(text))

然后调用打印函数,而不是代码中的 print(text)。

printing("START")
printing(datetime.datetime.now())
printing("COMPLETE")
printing(datetime.datetime.now())
于 2018-11-28T19:02:04.140 回答
0

这是对@UltraInstinct 的 Tee 类的一个小改进,被修改为上下文管理器并且还捕获任何异常。

import traceback
import sys

# Context manager that copies stdout and any exceptions to a log file
class Tee(object):
    def __init__(self, filename):
        self.file = open(filename, 'w')
        self.stdout = sys.stdout

    def __enter__(self):
        sys.stdout = self

    def __exit__(self, exc_type, exc_value, tb):
        sys.stdout = self.stdout
        if exc_type is not None:
            self.file.write(traceback.format_exc())
        self.file.close()

    def write(self, data):
        self.file.write(data)
        self.stdout.write(data)

    def flush(self):
        self.file.flush()
        self.stdout.flush()

要使用上下文管理器:

print("Print")
with Tee('test.txt'):
    print("Print+Write")
    raise Exception("Test")
print("Print")
于 2019-07-12T14:00:50.453 回答