我的班级构造了一个以 init ()中的班级命名的记录器。现在,当我记录一条消息时,对于到目前为止已创建的该类的每个实例,我都会得到一条消息的副本。如何避免这种重复?
我还担心这可能只是一个更深层次问题的征兆-这是一种浪费性的内存管理方法,可一次实例化几百个类吗?有没有更明智的方式来处理跨多个类的日志记录?
尽管下面的代码是问题的简单再现,但是实际的代码是非常模块化的,并且每个类可以通过各种不同的应用程序以许多不同的方式使用。每个类都可以用作由其定义的main()方法调用的独立类,也可以从另一个类或三个或四个主要应用程序之一中调用。日志记录方法需要考虑到这种模块化。
import logging
class person:
def __init__(self,name):
self.name = name
logger = logging.getLogger('person logger')
logger.setLevel(logging.DEBUG)
ch = logging.StreamHandler()
formatter = logging.Formatter('%(name)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.info(f'{self.name} exists')
if __name__ == '__main__':
for name in ["Alice", "Bob", "Carlos"] :
a = person(name)
预期结果:
person logger - Alice exists
person logger - Bob exists
person logger - Carlos exists
实际结果:
person logger - Alice exists
person logger - Bob exists
person logger - Bob exists
person logger - Carlos exists
person logger - Carlos exists
person logger - Carlos exists
答案 0 :(得分:4)
使用if logger.handlers
检查是否已经有处理程序。或者,您每次创建该person
对象时都要添加处理程序。
基本上:
import logging
class person:
def __init__(self,name):
self.name = name
logger = logging.getLogger('person logger')
logger.setLevel(logging.DEBUG)
if not logger.handlers:
ch = logging.StreamHandler()
formatter = logging.Formatter('%(name)s - %(message)s')
ch.setFormatter(formatter)
logger.addHandler(ch)
logger.info(f'{self.name} exists')
if __name__ == '__main__':
for name in ["Alice", "Bob", "Carlos"] :
a = person(name)
此外,大多数情况下,我们不是为类而是为模块创建记录器。
对于一个大型项目,创建一个log_helper
模块,其中可能包含初始化函数:
def getLogger(name):
logger = logging.getLogger(name)
# do some initialization...
# like adding handlers
return logger
在每个模块的顶部获取记录器:
# person.py Module person
import log_helper
logger = log_helper.getLogger("person") # or whatever you want
# just use this logger...