将函数转换为可返回一个实例的单例类 [英] Converting a function into a singleton class that returns one instance

查看:49
本文介绍了将函数转换为可返回一个实例的单例类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am doing this project on Python 2.7 and I am trying to convert this function that returns a logging object. I am trying to make sure that I can utilize the same object instance through different python modules by importing it without actually creating new instances? For e.g if I actually import the module where the instance was created originally, each time I import it a new instance gets created. But I want to use the same original instance, throughout all different modules, that was created the first time I ran that module since multiple lines are being printed out inside my log file due to multiple instances. That is why a singleton class in Python 2.7 is required but I am not sure how to convert this function into a singleton class such that it returns one instance and I can use it throughout all my different modules by importing without triggering new instances. The setLogger function creates a logger instance which inputs logs into the file_name log file.

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

推荐答案

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

I don't understand why different loggers are generated when using the same name.

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

To force a single logger instance, get the logger once and store it in a global variable.

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

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

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

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

I set up some modules to narrow down the issue.

--- 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.

I ran moda.py. Here is the output. The logger is created once and every module uses the same instance of the logger. All messages are saved to the same file. Note that I'm using 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

这篇关于将函数转换为可返回一个实例的单例类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆