我想记录有关某个实例的信息。但是,我想根据我使用的日志级别显示不同的详细程度。例如:
LOGGER.level
# => 20
LOGGER.info('Car info: %s', Car())
# => [INFO]: Car info: Celica
LOGGER.setLevel(logging.DEBUG)
LOGGER.info('Car info: %s', Car())
# => [INFO]: Car info: {'name': 'Celica', 'year': 1998, 'model': 'GT-Four'}
到目前为止,我想到了以下内容:
import logging
LOGGER = logging.getLogger()
logging.basicConfig(
format='[%(levelname)s]: %(message)s',
level=logging.INFO)
class Car:
def __init__(self):
self.name = 'Celica'
self.year = 1998
self.model = 'GT-Four'
def __repr__(self):
if LOGGER.level == logging.DEBUG:
return str(self.__dict__)
return f'{self.name}'
我觉得这有点“习惯”,并且以某种方式进行了硬编码。在LOGGER
中使用logging
或__repr__
感觉有些奇怪。这是正确的进行方法还是有更好的方法?
答案 0 :(得分:1)
是的,在__repr__
中包含逻辑是不寻常的-如您所识别的,可能是代码气味。通常,表示逻辑将放在Formatter
子类中,但您也可以在filter中进行。这是一个简单的工作示例;您应该能够将基本概念改编为更通用的方案:
import logging
LOGGER = logging.getLogger()
class Car:
def __init__(self):
self.name = 'Celica'
self.year = 1998
self.model = 'GT-Four'
def filter(record):
if record.args:
args = []
for arg in record.args:
if isinstance(arg, Car):
if record.levelno == logging.DEBUG:
arg = str(arg.__dict__)
else:
arg = arg.name
args.append(arg)
record.args = tuple(args)
return True
def main():
LOGGER.setLevel(logging.DEBUG)
f = logging.Formatter('[%(levelname)-5s]: %(message)s')
h = logging.StreamHandler()
h.setFormatter(f)
LOGGER.addHandler(h)
LOGGER.addFilter(filter)
car = Car()
LOGGER.info('basic : %s', car)
LOGGER.debug('detail: %s', car)
LOGGER.debug('no car in this %s', 'message')
LOGGER.debug('nor in this one')
if __name__ == '__main__':
main()
运行时,以上脚本将打印:
[INFO ]: basic : Celica
[DEBUG]: detail: {'name': 'Celica', 'year': 1998, 'model': 'GT-Four'}
[DEBUG]: no car in this message
[DEBUG]: nor in this one