2012-09-26 22 views
1

我想登录到一个文本文件,无论是print编辑sys.stdout。虽然我明白聪明的人能拿出更优雅和Python的解决方案,这是我的解决方案如何用导入语句覆盖python builtins?

class logger: 

    def __init__(self, filename='log.txt'): 
    self.logf = open(filename, 'a') 

    global print 
    self.__print = print 

    print = self.lognprint 

    def __del__(self): 
    self.logf.close() 

    def lognprint(self, *args, **keywords): 
    self.__print(*args, file = self.logf, **keywords) 
    self.__print(*args, **keywords) 

现在如果在我的代码的任何地方我想补充

mylog = logger() 

东西都print ED事后也记录。

但很多明显的原因,这是不是安全/良好。例如多个logger对象可能是讨厌的。

另外我对

from __future__ import print_function 

启发(见this例如),我想要做类似的事情,所以,当我import我的模块,内建print是我的版本打印的任何地方覆盖在代码中。

这怎么可能?

+0

请告诉我你用这个来记录你不能**改变的第三方程序的'print'输出。如果不是(==如果它是你自己的使用'print'的代码):改变它使用[logging](http://docs.python.org/library/logging.html)模块。 –

+3

您总是可以通过'__builtins __。print'引用内置的打印功能。无需在新变量中捕获它。 –

+0

@LukasGraf'我正在使用它来从第三方程序'打印'输出,我**不能**改变',_tell我你想听到什么_ –

回答

1

而不是把你的代码放在类中,把它放在模块级别。这种方式,将被第一次导入模块执行:

# logging.py 
print = my_print 
1

类似的解决方案,或记录的东西到一个文件,该文件也印到std.out,在logging cookbook给出。
这里是你如何可以简单地记录的东西到名为“spam.log”,同时也文件打印某些东西std.out:

import logging 

logger = logging.getLogger('simple_example') 
logger.setLevel(logging.DEBUG) 
# create file handler which logs even debug messages 
fh = logging.FileHandler('spam.log') 
fh.setLevel(logging.DEBUG) 
# create console handler with a higher log level 
ch = logging.StreamHandler() 
ch.setLevel(logging.ERROR) 
# create formatter and add it to the handlers 
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 
ch.setFormatter(formatter) 
fh.setFormatter(formatter) 
# add the handlers to logger 
logger.addHandler(ch) 
logger.addHandler(fh) 

# 'application' code 
logger.debug('debug message') 
logger.info('info message') 
logger.warn('warn message') 
logger.error('error message') 
logger.critical('critical message') 

在这个例子中的所有邮件转到文件,只有更高的水平去控制台。