Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.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 2.7_Logging_Singleton_Single Instance - Fatal编程技术网

Python 将函数转换为返回一个实例的单例类

Python 将函数转换为返回一个实例的单例类,python,python-2.7,logging,singleton,single-instance,Python,Python 2.7,Logging,Singleton,Single Instance,我在Python2.7上做这个项目,我试图转换这个返回日志对象的函数。我试图通过导入相同的对象实例而不实际创建新实例来确保通过不同的python模块使用相同的对象实例?例如,如果我实际导入了最初创建实例的模块,则每次导入时都会创建一个新实例。但我想使用相同的原始实例,在所有不同的 模块,这是我第一次运行该模块时创建的,因为由于多个实例,日志文件中打印了多行。这就是为什么Python2.7中需要一个singleton类,但我不知道如何将此函数转换为singleton类,以便它返回一个实例,并且我可

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

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
  import mylogger

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

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

  modc.writelog()
  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()
--modc.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
  import mylogger

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

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

  modc.writelog()
  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()
--modb.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
  import mylogger

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

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

  modc.writelog()
  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--

  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
  import mylogger

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

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

  modc.writelog()
  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

此函数的行为方式已达到预期效果。它将始终返回相同的记录器对象,因为
logging.getLogger
会处理该问题。@zvone No它不会。每次调用此函数时,它都会创建一个不同的实例。我正在从不同的模块调用包含此函数的模块。所以每次调用它时,它都会创建不同的对象实例。但是我希望整个
\uuuu name\uuuu
中都有相同的实例,这就是为什么为每个模块创建不同日志的原因。您可以使用任何字符串作为名称。对于每个实例调用,请尝试
logger=logging.getLogger('MyLog')
,以便每次都使用相同的日志。@Mike67我只是尝试用“MyLog”替换名称,但它不起作用。我明确地打印出了创建的对象,它们对于不同的模块都是不同的。这种逻辑是有道理的,但您必须理解,这个setLogger函数本身就位于一个名为lets say debugLogs.py的模块中。因此,假设我尝试在一个名为a.py的文件中设置记录器,我将导入debugLogs.py和setup logger。然后,另一个模块B.py尝试设置记录器并调用debugLogs.py,但即使对于B.py,记录器最初也会设置为“无”,因此我们再次为不同的文件获取不同的对象。您认为逻辑应该是这样的:只有当我们从A.py logger调用时,才设置了logger,并且我们可以通过其他模块重用A.py创建的logger对象。