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 数据框或自定义类,以供全球使用?
实际上,这不是推荐的方法,我从未见过它在实际代码中使用过。
推荐的方法是使用模块,因为模块已经具有“全局”命名空间(有关、 和 的更多信息,请参阅此答案)。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)
这是不建议:
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)