在应用中共享配置的Python模式
我有一个应用程序,它由一个基础应用和几个模块组成。基础应用会读取一个参数文件,把内容放进一个配置哈希里,我想把这个配置在所有模块之间共享。
现在,我是把一个“父”对象传递给模块,然后这些模块通过像 self.parent.config 这样的方式来获取配置。
但是,由于模块之间有好几个层级,我发现自己不得不写像 self.parent.parent.config 这样的代码,这看起来就不太好。
有没有什么更好的方法来在应用程序和它的模块之间共享配置对象?我在考虑创建一个“配置”模块,这个模块基本上会创建一个全局的配置变量,可以由基础应用设置,然后其他模块可以导入并访问这个变量,但我不确定这样使用全局变量是否有其他不好的影响。
我对Python还比较新,所以请多多包涵 =)
4 个回答
我觉得你说的“模块”,其实是指“类/对象”。对象是类的一个实例,比如:
class MyClass(object):
def __init__(self, ...):
...
...
myObject = MyClass()
模块就是一个.py文件,你可以这样导入:
import mymodule
看起来不太可能你创建的所有类都需要访问一个全局配置。不过,如果你确实需要你应用里的所有东西都能访问一些全局参数,你可以把它们放在你自己的config
模块里:
myParam1 = 1
myParam2 = 2
然后从任何模块、任何对象,甚至任何地方,只要你执行了import config
,你就可以直接说print(config.myParam1)
另外,如果你想让一大堆对象共享同一个属性,你不需要通过手动设置self.parent
来引用它。只要你使用继承,你就可以做类似这样的事情:
class Parent(object):
def __init__(self, theConfig):
self.theConfig = theConfig
class Child(Parent):
...
def method(self,...):
print(self.theConfig)
回答一个旧问题:
只需使用依赖注入,就像@Reed Copsey在这里建议的那样。比如:
class MyClass:
def __init__(self, myConfig):
self.myConfig = myConfig
...
def foo(self):
self.myConfig.getConfig(key)
...
self.myConfig.setConfig(key,val)
...
...
# myConfig is your configuration management Module/Class
obj = SomeClass(myConfig)
你可以这样做:
import config
然后就可以有一个全局的配置模块。
以下是我评论中的一些摘录:
你总是可以通过这样写来为特殊情况添加规则:oddValue if isOddSituation() else config.normalValue
。
如果你想让配置模块可以层级继承(就像我之前的回答中提到的那样),那么你可以把配置表示成一个类,或者使用copy
模块来做一个浅拷贝并进行修改,或者你可以使用一个“配置字典”,例如:
import config as baseConfig
config = dict(baseConfig, overriddenValue=etc)
其实你处于哪个范围并不是特别重要。