【问题标题】:Borg Design Pattern博格设计模式
【发布时间】:2016-01-02 17:57:02
【问题描述】:

我正在尝试学习 Python 中的设计模式。实现全局变量的推荐方法是通过 Borg 模式。

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state

这似乎是一本字典。我将如何存储更复杂的数据结构,例如 Pandas 数据框或自定义类,以供全球使用?

【问题讨论】:

    标签: python oop design-patterns


    【解决方案1】:

    实际上,这不是推荐的方法,而且我从未见过它在实际代码中使用过。

    推荐的方法是使用模块,因为模块已经具有“全局”命名空间(有关 globals()locals()vars() 的更多信息,请参阅 this answer)。


    但是,为了便于理解:

    到目前为止,您所拥有的只是实例级别的共享状态的基本框架。您现在需要的是您要跟踪的其余状态:

    class Config(Borg):
    
        def __init__(self, config_file):
            super(Config, self).__init__()
            # load and parse file, saving settings to `self`
    

    此方法的一个缺点是您可以有多个实例消耗内存,它们都知道相同的事情。 (内存不多,真的。)

    另一种实现“共享状态”的方法是只创建一个实例,然后让类始终返回同一个实例——也称为singleton

    class Config(object):
    
        the_one = None
    
        def __new__(cls, config):
            if cls.the_one is None:
                cls.the_one = Super(Config, cls).__new__(cls)
                # load and parse file, saving settings to `cls.the_one`
            return cls.the_one
    

    任何一种方法都会导致以下结果:

    >>> config = Config('my_config_file.cfg')
    >>> config.screen_size
    # whatever was saved during the loading and parsing of the config file
    # for 'screen_size'
    

    【讨论】:

      【解决方案2】:

      这是推荐的:

      class Borg:
          __shared_state = {}
          def __init__(self):
              self.__dict__ = self.__shared_state # ***
      

      绝对不需要具有相同__dict__ 的不同对象。在这里,您使每个实例都保存完全相同的数据。您不妨将对象设为单例并避免创建冗余对象:

      class Borg(object):
          instance = None
          def __new__(cls):
              if cls.instance is None:
                  cls.instance = super(Borg, cls).__new__(cls)
              return cls.instance
      
      >>> b1 = Borg()
      >>> b2 = Borg()
      >>> b1 is b2
      True
      

      但为什么还要这样做呢?模块本质上是具有命名空间的单例,您可以在其中存储数据和功能。

      我只会使用一个模块。

      如何存储更复杂的数据结构,比如 Pandas 数据框或自定义类,以供全球使用?

      简单 - 将数据存储在模块的全局变量中(例如 module.py),如下所示:

      global_dataframe = pandas.DataFrame()
      
      class CustomClass:
          """my Python class definition"""
      

      global_dataframeCustomClass 现在都是模块级全局变量。您可以导入它们所在的模块,并通过点查找来引用它们。

      >>> import module
      >>> module.global_dataframe
      Empty DataFrame
      Columns: []
      Index: []
      >>> module.CustomClass
      <class module.CustomClass at 0x7fdf73f3d0b8>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-28
        • 2023-03-19
        • 1970-01-01
        相关资源
        最近更新 更多