Python使用存储在其他文件中的变量覆盖配置文件

时间:2016-10-12 09:02:48

标签: python-2.7 configuration config overrides

假设我有一个名为main_config.pycustom_config.py的文件。它们都在同一模块中。

我想要做的是有两个单独的配置文件,其中一个(主要)是版本控制的,另一个(自定义)是.gitignore以允许不同的设置有他们的使用main文件作为模板进行配置。

下面的代码曾经在Python 3.5上正常工作,但我被迫恢复到2.7并且它不再按预期工作。我究竟做错了什么?我在使用KeyError: 'client2'的行上获得exec例外。

main_config.py的内容:

class MainConfig(object):
    clients = {
        "client1" = {
            "IP" = "127.0.0.1",
            "User" = "admin"
        }
    }

    try:
        with(open(__file__.replace("main_config.py", "custom_config.py")) as source_file:
            exec(source_file.read())
    except IOError, e:
        print("No custom config detected")

custom_config.py的内容:

from (...).main_config import MainConfig

MainConfig.clients["client2"]["IP"] = "0.0.0.0"
MainConfig.clients["client2"]["User"] = "root"

2 个答案:

答案 0 :(得分:1)

我看到您使用字典和=符号代替:

除此之外,您无法在未指定IP的情况下分配client2,因此您的代码可能如下所示:

main_config.py

class MainConfig(object):
    clients = {
        "client1" : {
            "IP" : "127.0.0.1",
            "User" : "admin"
        }
    }

    try:
        with(open(__file__.replace("main_config.py", "custom_config.py")) as source_file:
            exec(source_file.read())
    except IOError, e:
        print("No custom config detected")

custom_config.py

    from (...).main_config import MainConfig

if 'client2' not in MainConfig.clients.keys():
    MainConfig.clients["client2"] = {}
MainConfig.clients["client2"]["IP"] = "0.0.0.0"
MainConfig.clients["client2"]["User"] = "root"

答案 1 :(得分:1)

我没有解释如何解决您遇到的具体错误(其他答案已经这样做了),但我还是喜欢 指出有更适合您的用例的配置语言。具体来说,Figura 原生支持这种可覆盖性。

以下是一个例子:

# main_config.py
class MainConfig:
    class clients:
        class client1:
            IP = "127.0.0.1"
            User = "admin"

# custom_config.py
class CustomConfig:
    # declare this config is meant to be applied as an override to another
    __override__ = True
    class client2:
        IP = "0.0.0.0"
        User = "root"

将它们组合在您的代码中:

from figura import build_config
full_config = build_config('main_config.MainConfig', 'custom_config.CustomConfig')

灵活的build_config函数将第一个arg视为基本配置,其余作为覆盖以应用于它。

完全披露:我是figura的作者。