博格设计模式

Ric*_*Foo 3 python oop design-patterns

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

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state
Run Code Online (Sandbox Code Playgroud)

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

Eth*_*man 5

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

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


但是,为了理解:

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

class Config(Borg):

    def __init__(self, config_file):
        super(Config, self).__init__()
        # load and parse file, saving settings to `self`
Run Code Online (Sandbox Code Playgroud)

这种方法的一个缺点是,您可能有多个实例消耗内存,但它们都知道相同的事情。(没有多少记忆,真的。)

另一种实现“共享状态”的方法是只创建一个实例,然后让类始终返回同一个实例——也称为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
Run Code Online (Sandbox Code Playgroud)

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

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


Aar*_*all 5

这是建议:

class Borg:
    __shared_state = {}
    def __init__(self):
        self.__dict__ = self.__shared_state # ***
Run Code Online (Sandbox Code Playgroud)

完全没有必要使用相同的__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
Run Code Online (Sandbox Code Playgroud)

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

我只会使用一个模块。

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

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

global_dataframe = pandas.DataFrame()

class CustomClass:
    """my Python class definition"""
Run Code Online (Sandbox Code Playgroud)

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

>>> import module
>>> module.global_dataframe
Empty DataFrame
Columns: []
Index: []
>>> module.CustomClass
<class module.CustomClass at 0x7fdf73f3d0b8>
Run Code Online (Sandbox Code Playgroud)