Я понимаю, что этот вопрос был задан ранее (Как лучше всего использовать файл настроек в Python?), но, учитывая, что этот вопрос был задан 7 лет назад, я считаю, что уместно обсудить еще раз, видя, как развивались технологии.
У меня есть проект Python, который требует использования разных конфигураций в зависимости от значения переменной среды. Поскольку использовать переменную среды для выбора файла конфигурации достаточно просто, мой вопрос заключается в следующем:
Какой формат считается лучшим в индустрии программного обеспечения для настройки файла конфигурации на Python, когда требуется несколько конфигураций в зависимости от среды?
Я понимаю, что python поставляется с модулем ConfigParser, но мне было интересно, может быть, лучше использовать такой формат, как YAML или JSON, из-за роста популярности из-за простоты их использования на разных языках. Какой формат легче поддерживать при наличии нескольких конфигураций?
Кроме того, похоже, что за несколько часов до закрытия этого вопроса была проведена общая очистка - все устаревшие ответы были удалены, а один из других ответов был отредактирован, чтобы предоставить обновленную информацию о YAML (и с тех пор был обновлен снова).
Между тем сравнительная «популярность» JSON особого значения не имеет. Вопрос в том, что будет наиболее знакомо или полезно вашим реальным пользователям в вашем реальном приложении. Существуют явные преимущества и недостатки формата INI / rc, исполняемого кода Python, JSON и т. д. Если бы был один ответ, который был бы лучшим для всех возможных применений, у нас не было бы даже более конкурирующих способов сделать это сегодня, чем у нас было десять лет назад, мы все использовали бы один. (Хотя, по крайней мере, у нас больше нет «действительно сложного языка XML с неявной, но нигде не определенной схемой» очень часто…)
Достаточно справедливо, я скорректирую свой вопрос, чтобы попытаться быть менее ценным. Конечно, у каждого формата есть свои преимущества, но, безусловно, в индустрии программного обеспечения должен быть некоторый консенсус в отношении того, что считается «передовой практикой». В конце концов, это очень тривиальное дизайнерское решение, которое необходимо принять, но я хочу выяснить, что является общим консенсусом в отрасли или самой арендой в некоторых рабочих областях.
Что ж, «хотя бы на некоторых рабочих местах» и есть проблема. В разных рабочих областях есть разные ответы. Частично это обусловлено используемыми технологиями (магазины Django, скорее всего, будут иметь исполняемые конфигурации, магазины полиглотов, которые смешивают много Python и Ruby, чтобы иметь YAML и т. д.), Но это также обусловлено конкретными потребностями их приложений. / пользователи. И ни одно из этих соображений не имеет общего ответа, применимого к «отрасли» в целом. Именно поэтому для этого все еще существует так много «отраслевых стандартов».






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