How to override python builtins with an import statement?

我只是一个虾纸丫 提交于 2019-12-11 10:52:25

问题


I want to log to a text file whatever is printed 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 printed 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!