问题
I want to log to a text file whatever is print
ed to sys.stdout
. While I understand smarter people can come up with more elegant and Pythonic solutions, here is my solution
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)
now if anywhere in my code I add
mylog = logger()
anything that is print
ed afterwards is also logged.
But for many obvious reasons this is not safe/good. For example multiple logger
objects can be nasty.
In addition I am inspired by
from __future__ import print_function
(see this for example) and I want to do something similar, so that when I import
my module, the builtin print
is overridden by my version of print anywhere in the code.
How is that possible?
回答1:
A similar solution, or logging stuff to a file, which also printed to std.out, is given in the logging cookbook.
Here is how you can simply log stuff to a file called 'spam.log' and also print certain stuff to 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')
In this example all messages go to the file, only higher levels go to console.
回答2:
Instead of placing your code inside the class, put it at the module level. This way it will be executed the first time the module is imported:
# logging.py
print = my_print
来源:https://stackoverflow.com/questions/12609705/how-to-override-python-builtins-with-an-import-statement