在应用中共享配置的Python模式

34 投票
4 回答
23507 浏览
提问于 2025-04-16 16:00

我有一个应用程序,它由一个基础应用和几个模块组成。基础应用会读取一个参数文件,把内容放进一个配置哈希里,我想把这个配置在所有模块之间共享。

现在,我是把一个“父”对象传递给模块,然后这些模块通过像 self.parent.config 这样的方式来获取配置。

但是,由于模块之间有好几个层级,我发现自己不得不写像 self.parent.parent.config 这样的代码,这看起来就不太好。

有没有什么更好的方法来在应用程序和它的模块之间共享配置对象?我在考虑创建一个“配置”模块,这个模块基本上会创建一个全局的配置变量,可以由基础应用设置,然后其他模块可以导入并访问这个变量,但我不确定这样使用全局变量是否有其他不好的影响。

我对Python还比较新,所以请多多包涵 =)

4 个回答

0

我觉得你说的“模块”,其实是指“类/对象”。对象是类的一个实例,比如:

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)
10

回答一个旧问题:

只需使用依赖注入,就像@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)
18

你可以这样做:

import config

然后就可以有一个全局的配置模块。


以下是我评论中的一些摘录:

你总是可以通过这样写来为特殊情况添加规则:oddValue if isOddSituation() else config.normalValue

如果你想让配置模块可以层级继承(就像我之前的回答中提到的那样),那么你可以把配置表示成一个类,或者使用copy模块来做一个浅拷贝并进行修改,或者你可以使用一个“配置字典”,例如:

import config as baseConfig
config = dict(baseConfig, overriddenValue=etc)

其实你处于哪个范围并不是特别重要。

撰写回答