我正在编写一些代码,将日志输出到屏幕或文件,但不是两者。 我认为最简单的方法是编写一个类:
class WriteLog:
"write to screen or to file"
def __init__(self, stdout, filename):
self.stdout = stdout
self.logfile = file(filename, 'a')
def write(self, text):
self.stdout.write(text)
self.logfile.write(text)
def close(self):
self.stdout.close()
self.logfile.close()
然后称之为:
output = WriteLog(sys.stdout, 'log.txt')
但是,我不确定如何允许在两者之间切换,即类中应该有一个选项可以将WriteLog
设置为使用stdout或filename
。设置该选项后,我只需使用WriteLog
,而无需if
语句等。
有什么想法吗?我在网上看到的大多数解决方案都试图同时输出。
感谢。
答案 0 :(得分:1)
我不是它的专家,但尝试使用logging library,也许你可以拥有2个处理程序的记录器,一个用于文件,一个用于流,然后动态添加/删除处理程序。
答案 1 :(得分:1)
也许是这样的?它使用符号名称'stdout'
或'stderr
'在构造函数中,或真正的文件名。 if
的用法仅限于构造函数。顺便说一句,我认为你试图过早地优化(这是所有邪恶的根源):你在现实生活中试图节省if
的时间,该程序将花费更多的时间在文件I / O;使if
的潜在浪费可以忽略不计。
import sys
class WriteLog:
def __init__(self, output):
self.output = output
if output == 'stdout':
self.logfile = sys.stdout
elif output == 'stderr':
self.logfile = sys.stderr
else:
self.logfile = open(output, 'a')
def write(self, text):
self.logfile.write(text)
def close(self):
if self.output != 'stdout' and self.output != 'stderr':
self.logfile.close()
def __del__(self):
self.close()
if __name__ == '__main__':
a = WriteLog('stdout')
a.write('This goes to stdout\n')
b = WriteLog('stderr')
b.write('This goes to stderr\n')
c = WriteLog('/tmp/logfile')
c.write('This goes to /tmp/logfile\n')
答案 2 :(得分:0)
我喜欢有关使用日志库的建议。但是如果你想自己破解某些东西,也许传递文件句柄是值得考虑的。
import sys
class WriteLog:
"write to screen or to file"
def __init__(self, output):
self.output = output
def write(self, text):
self.output.write(text)
def close(self):
self.output.close()
logger = WriteLog(file('c:/temp/log.txt','a' ))
logger.write("I write to the log file.\n")
logger.close()
sysout = WriteLog(sys.stdout)
sysout.write("I write to the screen.\n")
答案 3 :(得分:0)
您可以使用logging库来执行与此类似的操作。以下函数将在INFO
级别设置日志记录对象。
def setup_logging(file_name, log_to_file=False, log_to_console=False ):
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
# Create Console handler
if log_to_file:
console_log = logging.StreamHandler()
console_log.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)-8s - %(name)-12s - %(message)s')
console_log.setFormatter(formatter)
logger.addHandler(console_log)
# Log file
if log_to_console:
file_log = logging.FileHandler('%s.log' % (file_name), 'a', encoding='UTF-8')
file_log.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(levelname)-8s - %(name)-12s - %(message)s')
file_log.setFormatter(formatter)
logger.addHandler(file_log)
return logger
您将日志的名称和您希望记录的位置(传递到文件,控制台或两者)传递给它。然后你可以在代码块中使用这个函数,如下所示:
logger = setup_logging("mylog.log", log_to_file=True, log_to_console=False)
logger.info('Message')
此示例将记录到名为mylog.log
的文件(在当前目录中)并具有如下输出:
2014-11-05 17:20:29,933 - INFO - root - Message
此功能有待改进的地方(如果您想添加更多功能)。现在,它会在INFO
行的日志级别.setLevel(logging.INFO)
上记录到控制台和文件。如果您愿意,可以动态设置。
此外,就像现在一样,您可以轻松添加标准日志记录行(logger.debug('Message')
,logger.critcal('DANGER!')
)而无需修改类。在这些示例中,调试消息不会打印(因为它设置为INFO
)而关键的消息将会打印出来。