Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从类记录器复制消息_Python_Python 3.x_Logging - Fatal编程技术网

Python 从类记录器复制消息

Python 从类记录器复制消息,python,python-3.x,logging,Python,Python 3.x,Logging,我的类构造了一个以init()中的类命名的记录器。现在,当我记录一条消息时,我会为迄今为止创建的类的每个实例获取一份消息副本。如何避免这种重复 我还担心这可能只是一个更深层次问题的症状——在一个一次可能实例化几百个类的应用程序中,这是一种浪费内存的方法吗?有没有一种更合理的方法来处理跨多个类的日志记录 虽然下面的代码是对问题的简单再现,但实际的代码是非常模块化的,每个类可能被各种不同的应用程序以许多不同的方式使用。每个类都可以用作独立类,由使用它定义的main()方法调用,也可以从另一个类调用,

我的类构造了一个以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

使用
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\u 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...

很有魅力,谢谢。我以为是多个记录器造成了问题,实际上是添加了多个处理程序。