简体   繁体   English

如何在 Python 中的模块之间共享相同的 object

[英]How to share a same object across modules in Python

I'm creating a simple logging module (I'm aware of logging , let me reinvent the wheel, one simpler, suited to my needs and on top of everything that allows me to learn in the way I make it).我正在创建一个简单的日志记录模块(我知道logging ,让我重新发明轮子,一个更简单的,适合我的需要,并且在所有允许我以我的方式学习的东西之上)。

I'm trying to mimic the API of logging , thus the core of the logging system is a Logger instance that contains a list of handlers , which eventually deliver the info either through the console (via a StreamHandler object) or to text files (via a FileHandler object).我试图模仿 API 的logging ,因此日志记录系统的核心是一个包含handlers列表的Logger实例,它最终通过控制台(通过StreamHandler对象)或文本文件(通过一个FileHandler对象)。 These classes are all defined in a module, which I import to the main program and the libraries I want to use logging on.这些类都定义在一个模块中,我将其导入到主程序和我想使用登录的库中。

The problem is that I'd like to define the logger just once , in the main program, and use it across the modules I import.问题是我只想在主程序中定义一次记录器,并在我导入的模块中使用它。 I do not want to define different loggers not only because I'd like to set the logging setup once, but also because this object includes the handling of files, and I'd like to make this centralised, not with various objects adding lines to the same file from different places.我不想定义不同的记录器,不仅因为我想设置一次记录设置,还因为这个 object 包括文件处理,我想让它集中化,而不是使用各种对象添加行来自不同地方的同一个文件。

What's the most pythonic way to define this pattern?定义这种模式的最 Pythonic 方式是什么?

you can define the logger in a class and use singleton pattern to be sure that the class will be instantiated only owns:您可以在 class 中定义记录器并使用 singleton 模式来确保 class 将被实例化仅拥有:

class SingletonMeta(type):
    """
    The Singleton class can be implemented in different ways in Python. Some
    possible methods include: base class, decorator, metaclass. We will use the
    metaclass because it is best suited for this purpose.
    """

    _instances = {}

    def __call__(cls, *args, **kwargs):
        """
        Possible changes to the value of the `__init__` argument do not affect
        the returned instance.
        """
        if cls not in cls._instances:
            instance = super().__call__(*args, **kwargs)
            cls._instances[cls] = instance
        return cls._instances[cls]


class Singleton(metaclass=SingletonMeta):
    def some_business_logic(self):
        """
        Finally, any singleton should define some business logic, which can be
        executed on its instance.
        """

        # ...


if __name__ == "__main__":
    # The client code.

    s1 = Singleton()
    s2 = Singleton()

    if id(s1) == id(s2):
        print("Singleton works, both variables contain the same instance.")
    else:
        print("Singleton failed, variables contain different instances.")

or you can define your logger as a class and use a decorator (cache method):或者您可以将您的记录器定义为 class 并使用装饰器(缓存方法):

def memoize(function):
  memo = {}
  def wrapper(*args):
    if args in memo:
      return memo[args]
    else:
      rv = function(*args)
      memo[args] = rv
      return rv
  return wrapper


class log:
    def __init__(self):
       ....
    def methdo(self):
       return logger

@memorize
def create_logger():

  return log.method()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM