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

Я'ве всегда используется в JSON файлы для настройки моего приложения. Я начал использовать их, когда я кодировал множество Java, и теперь я'м работает в основном на стороне сервера и науки данные разработки на Python и я не уверен, если в JSON это правильный путь, чтобы пойти больше.

Я'вэ видел сельдерея использовать фактический файлов Python для конфигурации. Изначально я был настроен скептически об этом. Но идея использовать простые структуры данных Python для конфигурации начинает расти на меня. Одни плюсы:

  • Структуры данных, будет таким же, как я'м, как правило, кодирование. Так что, я не'т нужно менять склад ума.
  • Моей среде IDE (PyCharm) понимает связь между конфигурацией и код. <и>сочетание клавиш Ctrl</роз> + <и>Б</роз> дает возможность переключаться между конфигурацию и код легко.
  • Я не'т необходимость работать с Имо ненужных строгий в JSON. Я'м смотрю на тебя двойные кавычки, без трейлинг-запятые и никаких замечаний.
  • Могу ли я написать конфигураций тестирования в приложении Я'м работает на, затем легко портировать их в файл конфигурации без необходимости выполнять какие-либо преобразования и разбора JSON.
  • Можно делать очень простые скрипты в файле конфигурации, если это действительно необходимо. (Хотя это должно быть очень ограничено.)

Итак, мой вопрос: если я перейду, как я стрелять себе в ногу?

Нет неквалифицированных конечный пользователь будет использовать файлы конфигурации. Любые изменения в файлах конфигурации, в настоящее время стремится к Git и выкатили на наших серверах в рамках непрерывного развертывания. Нет ручного изменения конфигурации, если есть чрезвычайная ситуация или находится в разработке.

(Я'вэ считать в YAML, но что-то он меня раздражает. Итак, сейчас он выключен американского стола.)

Комментарии к вопросу (25)
Решение

Используя скриптовый язык в конфигурационный файл выглядит на первый взгляд: у вас есть вся сила, что доступных языков и можете просто использовать eval()илиимпорт` его. На практике, есть несколько подводных камней:

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

  • это язык программирования, что означает, что config может сделать трудным для отладки. С нормальным файл config вы смотрите на него и видите, что значения для каждого свойства. Со скриптом, вы потенциально нужно выполнить его первым, чтобы увидеть значения.

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

  • это язык программирования, что означает, что в конфиге можно делать все, что язык программирования может сделать. Так что либо вы используете решения "песочницы", которая сводит на нет большую часть гибкости языка, или вы размещаете высокое доверие в конфиге автора.

Таким образом, используя скрипт для конфигурации, скорее всего, нормально, если аудитория вашего инструмента разработчики, например, Сфинкса config или setup.py в проектах на Python. Другие программы с исполняемым конфигурации оболочки, такие как bash, и редакторы, как ВИМ.

Используя язык программирования для конфигурации необходим, если в config содержит много условных разделов, или, если он обеспечивает обратные вызовы/Плагины. С помощью скрипта напрямую, вместо того, чтобы использовать eval()-Инг некоторые полевые конфигурации, как правило, более отладочном (думаю, что из трассировки стека и номера строк!).

Непосредственно с использованием языка программирования также может быть хорошей идеей, если ваш config-это так часто повторялось, что вы пишете скрипты для автоматической генерации конфигурации. Но, пожалуй, лучшей модели данных для конфига может устранить потребность в такой явной настройки? Например, это может быть полезно, если файл конфигурации может содержать заполнители, которые потом развернуть. Еще одна особенность иногда видел несколько конфигурационных файлов с разной очередностью, которые могут перекрывать друг друга, хотя это представляет некоторые из своих собственных проблем.

В большинстве случаев, ini-файлы, файлы свойств Java, или документы и YAML гораздо лучше подходят для конфигурации. Для сложных моделей данных, XML также могут быть применены. Как вы'вэ отметил, JSON есть некоторые аспекты, которые делают ее непригодной в качестве человека-редактируемый конфигурационный файл, хотя это хорошо формат обмена данными.

Комментарии (15)

+1 ко всему в Амон'ы ответ. Я'd нравится, чтобы добавить это:

Вы'll не пожалеете, используя код Python в качестве языка конфигурации первый раз, когда вы хотите импортировать такую же конфигурацию из кода, написанного на другом языке. Например, если код, что's частью вашего проекта и это написано в C++ или Ruby или что-то еще нужно было убрать в настройках, вы'll необходимо перейти по ссылке в интерпретаторе Python в качестве библиотеки или разбора конфигурации в Python coprocess, как неудобно, сложно, или требующие много ресурсов.

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

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

Редактировать для справки: несколько человек прокомментировали этот ответ о том, насколько вероятно или маловероятно, что проект будет успешно полностью переписан на другой язык. Это'ы справедливо сказать, что полную обратную совместимость переписывать, наверное, редко видели. Что я, собственно, имел в виду именно биты и куски того же проекта (и нужен доступ к одной и той же конфигурации), написанного на разных языках. Например, служащий стека в C++ для скорости, пакетный режим очистки базы данных на языке Python, часть скриптов в качестве клея. Так что тратить мысли на это дело тоже :)

Комментарии (14)

Другие ответы уже очень хорошо, я'МР просто принесите мой опыт использования в реальном мире в несколько проектов.

Плюсы

Они в основном уже прописано:

  • если вы находитесь в Python программа, парсинг ветерок (оценка); это работает автоматически, даже для более сложных типов данных (в нашей программе, у нас есть геометрические точки и преобразований, которые сбрасываются/загружается нормально через кат/оценка);
  • создание и "фальшивые конфигурации" с помощью всего нескольких строк кода тривиально;
  • вы лучше структур и, Имо, намного лучше, чем JSON синтаксис (блин даже просто комментарии и не успев поставить двойные кавычки вокруг ключей словаре большая читаемость победа).

Минусы

  • злоумышленники могут делать то, что ваша основная программа может делать; я не'т считаю это большой проблемой, поскольку, как правило, если пользователь может изменять файл конфигурации, он/она уже может делать все, что приложение может сделать;
  • если вы больше не в программах на Python, теперь у вас есть проблема. В то время как некоторые из наших конфигурационные файлы остались рядового до их первоначальной заявки, в частности, пришел для хранения информации используется несколько разных программ, большинство из которых в настоящее время на C++, который сейчас взломан-вместе анализатор для гипотетических небольшое подмножество питона кат. Это, очевидно, плохо.
  • Даже если ваша программа остается в Python, вы можете изменить версию Python. Позвольте'ы сказать, ваше приложение начал в Python 2; после многих испытаний вам удалось перенести его на Python 3 - к сожалению, вы не'т действительно тест весь код - у вас есть все конфигурационные файлы валяются на ваших клиентов' станки, написанных для Python 2, и на которые вы не'т действительно есть контроль. Вы даже не можете представить, что "режим совместимости", чтобы читать старые файлы конфигурации (что часто делается для форматов файлов), если вы не готовы пачка/вызова Python 2 переводчика!
  • Даже если вы находитесь в Python, изменение файл конфигурации от кода-это реальная проблема, потому что... ну, изменяя код не банальные, особенно код, который имеет богатый синтаксис, а не на Лиспе или похожие. Одной программе наш файл конфигурации, питона, написанная от руки, но который, как выяснилось позже, было бы полезно, чтобы манипулировать с помощью программного обеспечения (настройка, список вещей, который так проще на порядок, используя графический интерфейс). Это большая проблема, потому что:
  • даже просто выполняя синтаксический анализ→АСТ→переписать обратно нетривиально (Вы'МР заметили, что половина предлагаемых решений затем помеченные как "устаревшие, не использовать, не работает во всех случаях" - а);
  • даже если бы они работали, АСТ слишком низкого уровня; вы, как правило, заинтересованы в манипулировании результаты расчетов, проведенные в файл, а не действия, которые привели к нему;
  • что приводит нас к простому факту, что вы не просто измените значения, которые вы заинтересованы в, Потому что они могут быть получены путем сложных вычислений, которые вы не можете понять/манипулировать через ваш код.

Сравните это с JSON, ini или (не дай Бог!) XML, где в памяти представление всегда может быть отредактирован и перезаписан либо без потери данных (XML, где большинство дом Парсеры могут держать пробелы в текстовых узлов и комментариев узлов) или по крайней мере потерять всего форматирование (формат JSON, где сам формат не'т позволить гораздо больше, чем необработанные данные, которые Вы читаете).


Так что, как обычно, там'ов нет однозначного решения; мою нынешнюю политику по данному вопросу:

  • если файл конфигурации:
  • конечно, для приложения Python и частным ему - как, никто и никогда не пытаться читать из него;
  • рукописные;
  • из надежного источника;
  • использование целевого приложения типы данных-это действительно премиум-класса;

файл Python может быть действительным идеи;

  • если вместо:
  • там может быть возможность того, некоторые другие приложения чтения;
  • есть вероятность того, что этот файл может редактироваться с помощью приложения, возможно, даже мои приложения;
  • обеспечивается недоверенного источника.

а "только сведения" в формате может быть идея получше.

Обратите внимание, что это's не требуется, чтобы сделать один выбор - я недавно написал приложение, которое использует оба подхода. У меня есть почти-не-измененный файл с первой установки, настройки рукописные, где есть преимущества, имеющие хорошие бонусы на Python, и JSON-файл конфигурации редактировать в интерфейсе.

Комментарии (8)

Главный вопрос: вы хотите, чтобы ваш конфигурационный файл, чтобы быть в некоторых Тьюринг полный язык (как питон)? Если вы хотите, что вы могли бы также рассмотреть возможность включения некоторых других (Тьюринг-полного) скриптовый язык, как Хитрость или Луа (поскольку может быть воспринято как "проще", чтобы использовать, или для размещения, чем на Python; читать главу о Использование &ампер; встраивание Python). Я выиграл'т обсудить, что дальше (потому что другие ответы -например, Амона- говорили, что в глубине), но обратите внимание, что встраивание скриптового языка в ваше приложение основные архитектурный выбор, что следует учитывать очень рано, я действительно не'т рекомендовать делать этот выбор позже! Хорошо известный пример программа настраивается через то "сценарии" и это в GNU редактора Emacs редактор (или, возможно, Автокад в собственной сфере); так знайте, что если вы принимаете сценариев, для некоторых пользователей будет в конечном итоге использовать и, возможно, злоупотребления, ваша точка зрения - это средство обширно и сделать несколько тысяч строк скрипта; отсюда и выбор достаточно хороший скриптовый язык-это важно. Однако (по крайней мере в POSIX-системах), вы могли бы рассмотреть удобный для включения конфигурацию и"файл" динамически в расчете на время инициализации (конечно, оставив бремя вменяемый конфигурацию своего системного администратора или пользователя; на самом деле это конфигурация текст, который исходит из какого-то файла или из какой-то команды). Для этого, вы могли бы просто принять конвенциидокумент к), что файл конфигурации путь, начиная с, например,! или | на самом деле консоли команды что вы бы читать как [трубопровода][7]. Это оставляет пользователю выбор через какой-то "препроцессора" или "скриптовый язык" он является наиболее знакомы. <суп>(вы должны доверять вашим пользователей о проблемах безопасности, если вы принимаете динамически вычисляемое конфигурации)</суп> Таким образом в коде инициализации, ваш "основной" (например) согласиться с некоторыми и--config аргумент confarg и получить файл*configf; от него. Если аргумент начинается с ! (т. е. если (confarg[0]==&#39;!&#39;) ....), вы должны использовать configf = к popen(confarg+1, то "Р", У); и закрыть эту трубу с pclose(configf);. В противном случае вы должны использовать configf=с помощью функции fopen(confarg, что "Р", У); и близко, что файл с вызовом функции fclose(configf); (Дон'т забудьте проверить ошибки). См труба(7), к popen(3), функции fopen(3). Для приложения кодировкой в Python читать о ОС.к popen и т. д... <суп>(документ и для странных пользователей, желающих передать конфигурационный файл с именем !фу.конфиг пройти ./!фу.конфиг в обход к popen выше трюк)</SUP и ГТ; Кстати, такой трюк только для удобства (чтобы избежать необходимости продвинутого пользователя, например код какой скрипт для создания конфигурационный файл). Если пользователь хочет сообщить любую ошибку, он должен отправить вас автоматически файл конфигурации... Обратите внимание, что вы также можете разработать приложение с возможностью использования и нагрузки Плагины При инициализации времени, например, с функции выглядит(3) (и нужно доверять своему пользователю о том, что плагин). Опять же, это очень важное архитектурное решение (и нужно определить и обеспечить довольно стабильный АПИ и Конвенции О эти плагины и приложения). Для приложения закодированы в языке сценариев, таких как Python, вы могли бы также принять некоторые аргументы программы для ивал или эксес или аналогичные примитивы. Опять же, вопросы безопасности тогда озабоченность (дополнительно) пользователей. В отношении текстовом формате в файле конфигурации (будь то автоматически или нет), я считаю, что вы в основном нужно документа *Ну** (и выбор того или иного формата-это не то, что важно; однако я рекомендую, чтобы ваш пользователь мог ставить какие -пропущено - комментарии внутри него). Вы могли бы использовать JSON (желательно в JSON парсер принимать и пропускать комментарии с обычными // до Эол или`/...*/` ...), или YAML, XML или ini или вашу собственную вещь. Разбор конфигурационного файла достаточно легко (и вы'll найти во многих библиотеках, связанных с этой задачей).

[7]: https://en.wikipedia.org/wiki/Pipeline_(в Unix)

Комментарии (1)

Добавление к Амон'ы answer, вы рассматривали альтернативы? JSON-это, может быть, больше, чем нужно, но файлы Python, вероятно, даст вам проблемы в будущем по причинам, указанным выше.

Однако Python уже есть парсер конфига на конфиг очень простой язык, который может выполнить все ваши потребности. [МодулейConfigParser] (https://docs.python.org/3/library/configparser.html) реализует простой конфигурации языка.

Комментарии (12)

Я долгое время работал с некоторыми известный software, который имеет свои конфигурационные файлы написаны в TCL, так что идея не новая. Это работал очень хорошо, так как пользователи, которые не'т знать язык еще можно писать/редактировать простые файлы конфигурации с использованием единого набора заявлением значение имени, в то время как более опытные пользователи и разработчики могут тянуть сложные трюки при этом.

Я не'т считаю, что "конфиг файлов может сделать трудным для отладки" это актуальная проблема. Как долго, как ваше приложение не'т заставить пользователей писать скрипты, пользователи могут всегда использовать простых заданий в файлы конфигурации, которые вряд ли сложнее получить права по сравнению с JSON или XML.

Переписать config-это проблема, хотя это's не так плохо, как кажется. Обновление произвольного кода невозможно, но загрузка конфигурации из файла, изменить его и сохранить обратно. В принципе, если вы делаете некоторые скрипты в файл конфигурации, который не только для чтения, вы'будете просто в конечном итоге с эквивалентным список инструкций set, значение имени, как только он будет сохранен. Хороший намек на то, что это произойдет-это "не редактировать" и комментарий в начале файла.

Одна вещь, чтобы рассмотреть, что в ваших конфигурационных файлах, выиграл'т быть надежно чтения простого регулярного выражения на основе инструментов, таких как СЭД, но насколько я понимаю это уже не случай с вашей текущей JSON-файлы, так там's не много, чтобы потерять.

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

Комментарии (1)

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

  1. Параметры в исходный файл Python является технически частью исполняемый исходный код, а не файл только для чтения данных. Если идти по этому пути, вы, как правило, делать импорт конфигурации`, так, что бы на "удобство", было, вероятно, одной из главных причин, что люди начали с помощью файла Python в качестве config в первую очередь. Сейчас вы склонны совершить, что config.py в вашем РЕПО, в противном случае ваш конечный пользователь столкнется с запутанным ImportError, когда они пытаются запустить программу в первый раз.

  2. Предполагая, что вы на самом деле совершили этот config.py в вашем РЕПО, теперь членами вашей команды, вероятно, имеют разные параметры на разных условиях. Представьте, что когда-то некоторые члены случайно совершает его/ее местные конфигурационный файл в репо.

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

Теперь, используя только файл конфигурации, такие как универсальный формат JSON, можно избежать всех 3 вышеперечисленных проблем, ведь вы можете попросить пользователя, чтобы придумать свои собственные конфигурации.JSON и кормить его в вашу программу.

ЗЫ: это правда, что в JSON имеет много ограничений. 2 из ограничений, упомянутых в ОП, может быть решена некоторыми творчества.

{ на "фу" по: 123, на "баре": 456, на "placeholder" и: "все остальные строки в этот файл может содержать трейлинг-запятая"и }

Комментарии (0)