我即将重构一个建立在twisted 之上的python 项目的代码。到目前为止,我一直在使用一个简单的settings.py
模块来存储常量和字典,例如:
#settings.py
MY_CONSTANT='whatever'
A_SLIGHTLY_COMPLEX_CONF= {'param_a':'a', 'param_b':b}
大量的模块导入settings.py
来完成他们的工作。
我要重构项目的原因是因为我需要动态更改/添加配置参数。我即将采取的方法是将所有配置收集在一个单例中,并在需要时访问它的实例。
import settings.MyBloatedConfig
def first_insteresting_function():
cfg = MyBloatedConfig.get_instance()
a_much_needed_param = cfg["a_respectable_key"]
#do stuff
#several thousands of functions later
def gazillionth_function_in_module():
tired_cfg = MyBloatedConfig.get_instance()
a_frustrated_value = cfg["another_respectable_key"]
#do other stuff
这种方法有效,但感觉不合时宜且臃肿。另一种方法是将cfg
模块中的对象外部化,如下所示:
CONFIG=MyBloatedConfig.get_instance()
def a_suspiciously_slimmer_function():
suspicious_value = CONFIG["a_shady_parameter_key"]
MyBloatedConfig
不幸的是,如果我要更改另一个模块中的实例条目,这将不起作用。由于我使用的是反应器模式,因此将人员存储在本地线程上以及使用队列是没有问题的。
为了完整起见,以下是我用来实现单例模式的实现
instances = {}
def singleton(cls):
""" Use class as singleton. """
global instances
@wraps(cls)
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class MyBloatedConfig(dict):
....
是否有其他更 Pythonic 的方式来广播不同模块的配置更改?