Как лучше всего настроить файл конфигурации в Python

Я понимаю, что этот вопрос был задан ранее (Как лучше всего использовать файл настроек в Python?), но, учитывая, что этот вопрос был задан 7 лет назад, я считаю, что уместно обсудить еще раз, видя, как развивались технологии.

У меня есть проект Python, который требует использования разных конфигураций в зависимости от значения переменной среды. Поскольку использовать переменную среды для выбора файла конфигурации достаточно просто, мой вопрос заключается в следующем:

Какой формат считается лучшим в индустрии программного обеспечения для настройки файла конфигурации на Python, когда требуется несколько конфигураций в зависимости от среды?

Я понимаю, что python поставляется с модулем ConfigParser, но мне было интересно, может быть, лучше использовать такой формат, как YAML или JSON, из-за роста популярности из-за простоты их использования на разных языках. Какой формат легче поддерживать при наличии нескольких конфигураций?

Вопрос, о котором вы говорите, был закрыт как слишком широкий всего несколько месяцев назад. Ваша версия кажется еще шире.

abarnert 04.04.2018 07:59

Кроме того, похоже, что за несколько часов до закрытия этого вопроса была проведена общая очистка - все устаревшие ответы были удалены, а один из других ответов был отредактирован, чтобы предоставить обновленную информацию о YAML (и с тех пор был обновлен снова).

abarnert 04.04.2018 08:01

Между тем сравнительная «популярность» JSON особого значения не имеет. Вопрос в том, что будет наиболее знакомо или полезно вашим реальным пользователям в вашем реальном приложении. Существуют явные преимущества и недостатки формата INI / rc, исполняемого кода Python, JSON и т. д. Если бы был один ответ, который был бы лучшим для всех возможных применений, у нас не было бы даже более конкурирующих способов сделать это сегодня, чем у нас было десять лет назад, мы все использовали бы один. (Хотя, по крайней мере, у нас больше нет «действительно сложного языка XML с неявной, но нигде не определенной схемой» очень часто…)

abarnert 04.04.2018 08:10

Достаточно справедливо, я скорректирую свой вопрос, чтобы попытаться быть менее ценным. Конечно, у каждого формата есть свои преимущества, но, безусловно, в индустрии программного обеспечения должен быть некоторый консенсус в отношении того, что считается «передовой практикой». В конце концов, это очень тривиальное дизайнерское решение, которое необходимо принять, но я хочу выяснить, что является общим консенсусом в отрасли или самой арендой в некоторых рабочих областях.

Keegan Ferrett 04.04.2018 08:26

Что ж, «хотя бы на некоторых рабочих местах» и есть проблема. В разных рабочих областях есть разные ответы. Частично это обусловлено используемыми технологиями (магазины Django, скорее всего, будут иметь исполняемые конфигурации, магазины полиглотов, которые смешивают много Python и Ruby, чтобы иметь YAML и т. д.), Но это также обусловлено конкретными потребностями их приложений. / пользователи. И ни одно из этих соображений не имеет общего ответа, применимого к «отрасли» в целом. Именно поэтому для этого все еще существует так много «отраслевых стандартов».

abarnert 04.04.2018 08:31
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
4
5
8 059
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Я думаю, что рассмотрение стандартной конфигурации для модуля настроек Python Django является хорошим примером этого, поскольку веб-фреймворк Python Django чрезвычайно популярен для коммерческих проектов и, следовательно, является представителем индустрии программного обеспечения.

С конфигурационными файлами JSON или YAML он не слишком интересен - он просто использует модуль python с именем settings.py, который можно импортировать в любой другой модуль, которому требуется доступ к настройкам. Там же определяются настройки на основе переменных среды. Вот ссылка на пример файла settings.py для Django на Github:

https://github.com/deis/example-python-django/blob/master/helloworld/settings.py

Это действительно зависит от ваших требований, а не от популярности формата. Например, если вам нужны простые пары ключ-значение, файла INI будет более чем достаточно. Если вам нужны сложные структуры (например, массивы или словари), я бы выбрал JSON или YAML. JSON просто хранит данные (он больше предназначен для автоматического потока данных между системами), тогда как YAML лучше подходит для файлов, созданных человеком (или поддерживаемых, или читаемых), поскольку он имеет комментарии, вы можете ссылаться на значения в другом месте файла ... И Вдобавок ко всему, если вам нужна надежность, гибкость и средства для проверки правильной структуры файла (но не особо заботятся о ручном редактировании данных), я бы выбрал XML.

Ответ принят как подходящий

Если вы действительно хотите использовать конфигурацию YAML на основе среды, вы можете сделать это следующим образом:

config.py

import yaml
import os

config = None

filename = getenv('env', 'default').lower()
script_dir = os.path.dirname(__file__)
abs_file_path = os.path.join(script_dir, filename)
with open(abs_file_path, 'r') as stream:
    try:
        config = yaml.load(stream)
    except yaml.YAMLError as exc:
        print(exc)

Это действительно поздно для вечеринки, но это то, что я использую, и я доволен этим (если вы открыты для решения на чистом Python). Мне это нравится, потому что мои конфигурации могут быть установлены автоматически в зависимости от того, где это развернуто, с использованием переменных среды. Я не так давно этим пользуюсь, поэтому, если кто-то видит проблему, я все слышу.

Состав:

|--settings
   |--__init__.py
   |--config.py

config.py

class Common(object):
    XYZ_API_KEY = 'AJSKDF234328942FJKDJ32'
    XYZ_API_SECRET = 'KDJFKJ234df234fFW3424@#ewrFEWF'

class Local(Common):
    DB_URI = 'local/db/uri'
    DEBUG = True

class Production(Common):
    DB_URI = 'remote/db/uri'
    DEBUG = False

class Staging(Production):
    DEBUG = True

__init__.py

from settings.config import Local, Production, Staging
import os

config_space = os.getenv('CONFIG_SPACE', None)
if config_space:
    if config_space == 'LOCAL':
        auto_config = Local
    elif config_space == 'STAGING':
        auto_config = Staging
    elif config_space == 'PRODUCTION':
        auto_config = Production
    else:
        auto_config = None
        raise EnvironmentError(f'CONFIG_SPACE is unexpected value: {config_space}')
else:
    raise EnvironmentError('CONFIG_SPACE environment variable is not set!')

Если моя переменная среды установлена ​​в каждом месте, где существует мое приложение, я могу внести ее в свои модули по мере необходимости:

from settings import auto_config as cfg

Я также хотел бы воспользоваться тем фактом, что вам не нужно компилировать исходный код Python и использовать простые файлы Python для конфигурации. Но в реальном мире у вас может быть несколько сред, каждая из которых требует разной конфигурации, и вы также можете захотеть прочитать некоторую (в основном конфиденциальную) информацию из переменных окружения или файлов, которые не находятся в системе управления версиями (чтобы предотвратить их ошибочную фиксацию).

Вот почему я написал эту библиотеку: https://github.com/davidohana/kofiko, которые позволяют использовать простые файлы Python для конфигурации, но также могут переопределять эти параметры конфигурации из .ini или env-vars, а также поддерживать настройку для различных сред.

Сообщение об этом в блоге: https://medium.com/swlh/code-first-configuration-approach-for-python-f975469433b9

Другие вопросы по теме