我在项目中也碰到了一个日志输出的问题,我是基于以前vnpy的日志引擎做了下修改,
@singleton #自己写的单例装饰器
class LogEngine:
"""日志引擎"""
# 日志级别
LEVEL_DEBUG = logging.DEBUG
LEVEL_INFO = logging.INFO
LEVEL_WARN = logging.WARN
LEVEL_ERROR = logging.ERROR
LEVEL_CRITICAL = logging.CRITICAL
def __init__(self, fileName=''):
"""
初始化日志引擎
:param fileName: 日志文件名,主要是测试用
"""
self.logger = logging.getLogger()
# 设置日志格式
# self.formatter = logging.Formatter('%(asctime)s %(levelname)s: %(message)s')
self.formatter = logging.Formatter(
'%(asctime)s %(levelname)s: %(module)s.%(funcName)s %(lineno)d line %(message)s')
self.consoleHandler = None
self.fileHandler = None
# 设置日志级别
self.setLogLevel()
# 设置输出
if globalSetting['logConsole']:
self.addConsoleHandler()
if globalSetting['logFile']:
self.addFileHandler(fileName)
# 添加NullHandler防止无handler的错误输出
nullHandler = logging.NullHandler()
self.logger.addHandler(nullHandler)
self.initFunc()
# 日志级别函数映射
self.levelFunctionDict = {
self.LEVEL_DEBUG: self.debug,
self.LEVEL_INFO: self.info,
self.LEVEL_WARN: self.warn,
self.LEVEL_ERROR: self.error,
self.LEVEL_CRITICAL: self.critical,
}
def setLogLevel(self,level=globalSetting["logLevel"]):
"""设置日志级别"""
levelDict = {
"debug": self.LEVEL_DEBUG,
"info": self.LEVEL_INFO,
"warn": self.LEVEL_WARN,
"error": self.LEVEL_ERROR,
"critical": self.LEVEL_CRITICAL,
}
self.level = levelDict.get(level, self.LEVEL_CRITICAL)
# handler内输出级别可以单独设置,但是级别必须高于日志级别
self.logger.setLevel(self.level)
def addConsoleHandler(self):
if not globalSetting["logActive"]:
# 如果配置文件里没有开启日志记录,则不开启日志记录
return
"""添加终端输出"""
if not self.consoleHandler:
self.consoleHandler = logging.StreamHandler()
self.consoleHandler.setLevel(self.level)
self.consoleHandler.setFormatter(self.formatter)
self.logger.addHandler(self.consoleHandler)
def delConsoleHandler(self):
"""移除终端显示"""
if self.consoleHandler:
self.logger.removeHandler(self.consoleHandler)
self.consoleHandler = None
def addFileHandler(self, filename=''):
"""添加文件输出"""
if not globalSetting["logActive"]:
# 如果配置文件里没有开启日志记录,则不开启日志记录
return
if not self.fileHandler:
if not filename:
filename = 'ft_' + datetime.now().strftime('%Y%m%d') + '.log'
# filepath = getTempPath(filename)
filepath = getLogPath(filename)
self.fileHandler = logging.FileHandler(filepath)
self.fileHandler.setLevel(self.level)
self.fileHandler.setFormatter(self.formatter)
self.logger.addHandler(self.fileHandler)
def delFileHandler(self):
"""移除文件输出"""
if self.fileHandler:
self.logger.removeHandler(self.fileHandler)
self.fileHandler = None
def initFunc(self):
"""初始化各种记录方法"""
self.debug = self.logger.debug
self.info = self.logger.info
self.warn = self.logger.warning
self.error = self.logger.error
self.critical = self.logger.critical
self.exception = self.logger.exception
logger = LogEngine()
用的时候 就把它当一个模块使用 from *** import logger
logger.info(msg)
关于你的方法我做了下实验:
def func1():
pass
setattr(func1,'b',1)
print(func1.b)
def func2():
print(func2.b)
setattr(func2,'b',2)
func2()
def func3():
print(b)
setattr(func3,'b',3)
func3()
func 1和2 是可以的
func3 就报错
不知道你的函数 采用:
@Logger()
def my_func():
my_func.logger.info("0000")
这种方式行不行