将函数转换为单例 class 即 returns 一个实例

Converting a function into a singleton class that returns one instance

我在 Python 2.7 上做这个项目,我正在尝试将这个函数转换为 returns 一个日志对象。我试图通过导入它而不实际创建新实例来确保我可以通过不同的 python 模块使用相同的对象实例?例如,如果我实际上导入了最初创建实例的模块,则每次导入它时都会创建一个新实例。但我想在所有不同的地方使用相同的原始实例 模块,这是我第一次创建该模块时 运行 因为多个实例在我的日志文件中打印了多行。这就是为什么需要 Python 2.7 中的单例 class 但我不确定如何将此函数转换为单例 class 以便它 returns 一个实例并且我可以通过在不触发新实例的情况下导入,在我所有不同的模块中使用它。 setLogger 函数创建一个记录器实例,它将日志输入 file_name 日志文件。

def setLogger(file_name):
    logger = logging.getLogger(__name__)
    if not getattr(logger, 'handler_set', None):
        logger.setLevel(logging.INFO)
        stream_handler = logging.StreamHandler()
        file_handler = logging.FileHandler(file_name)
        formatter = logging.Formatter('%(message)s')
        file_handler.setFormatter(formatter)
        logger.addHandler(file_handler)
        logger.addHandler(stream_handler)
        logger.setLevel(logging.INFO)
        logger.propagate = False
        logger.handler_set = True
    return logger

我不明白为什么使用相同的名称会生成不同的记录器。

要强制使用单个记录器实例,获取记录器一次并将其存储在全局变量中。

logger = None  # global variable

def setLogger(file_name):
    global logger
    if logger == None:
       print('Creating logger')
       logger = logging.getLogger(__name__)  # only run once
    if not getattr(logger, 'handler_set', None):
        ........
    return logger

+++++++++++++++++++++++++++++++++++++++++++++ ++

我设置了一些模块来缩小问题范围。

--- mylogger.py ---

  import logging

  logger = None  # global variable

  def setLogger(file_name="LogOut.log"):
      global logger
      if logger == None:
         print('Creating logger')
         logger = logging.getLogger(__name__)  # only run once
      if not getattr(logger, 'handler_set', None):
          logger.setLevel(logging.INFO)
          stream_handler = logging.StreamHandler()
          file_handler = logging.FileHandler(file_name)
          formatter = logging.Formatter('%(message)s')
          file_handler.setFormatter(formatter)
          logger.addHandler(file_handler)
          logger.addHandler(stream_handler)
          logger.setLevel(logging.INFO)
          logger.propagate = False
          logger.handler_set = True
      return logger

--- modc.py ---

  import mylogger

  def writelog():
      print("Hello from " + __name__)
      print(__name__, 'LogID:', id(mylogger.setLogger()))
      mylogger.setLogger().warning("Hello from " + __name__)

--- modb.py ---

  import mylogger
  import modc

  def writelog():
      print("Hello from " + __name__)
      print(__name__, 'LogID:', id(mylogger.setLogger()))
      mylogger.setLogger().warning("Hello from " + __name__)

  modc.writelog()

--- moda.py ---

  import mylogger

  def writelog():
      print("Hello from " + __name__)
      print(__name__, 'LogID:', id(mylogger.setLogger()))
      mylogger.setLogger().warning("Hello from " + __name__)
      
  import modb
  import modc

  writelog()
  modb.writelog()
  modc.writelog()

我运行moda.py。这是输出。记录器只创建一次,每个模块都使用相同的记录器实例。所有消息都保存到同一个文件中。请注意,我使用的是 python 3.7.

  Hello from modc
  Creating logger
  modc LogID: 1764613056456
  Hello from modc
  Hello from __main__
  __main__ LogID: 1764613056456
  Hello from __main__
  Hello from modb
  modb LogID: 1764613056456
  Hello from modb
  Hello from modc
  modc LogID: 1764613056456
  Hello from modc