Python перезаписывает конфигурационный файл переменными, хранящимися в другом файле

#python-2.7 #configuration #config #overriding

#python-2.7 #конфигурация #переопределение

Вопрос:

Предположим, у меня есть файл с именем main_config.py and custom_config.py . Они оба находятся в одном модуле.

Что я хочу сделать, так это иметь два отдельных конфигурационных файла, где один из них (основной) контролируется версиями, а другой (пользовательский) является .gitignore ‘d, чтобы разные настройки имели свои собственные конфигурации с 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"
  

Ответ №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. Что касается : , и = вы заметили, да, это опечатка. Что касается остальной части ответа, это должно сработать, но я не понимаю, почему я не могу создавать ключи из другого файла без этого if предложения — в конце концов, если бы мои файлы не были разделены, я мог бы использовать такого рода создание ключей без предварительной проверки, существует ли ключ. И почему это работало в Python 3.5?

Ответ №2:

Я не объясняю, как решить конкретную ошибку, с которой вы сталкиваетесь (другие ответы уже делают это), но я хотел бы указать, что для вашего варианта использования есть более подходящие языки конфигурации. В частности, 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 обрабатывает первый аргумент как базовую конфигурацию, а остальные — как переопределения для применения к нему.

Полное раскрытие: я являюсь автором figura.

Комментарии:

1. Поддержано за другой подход к этой проблеме, но, к сожалению, я не могу использовать для этого другие модули.