Использование конфигурационных файлов, написанных на Python
Я заметил несколько пакетов Python, которые используют файлы конфигурации, написанные на Python. Помимо очевидного повышения привилегий, каковы плюсы и минусы этого подхода?
Есть ли большой приоритет для этого? Есть ли какие-либо руководства, как лучше всего это реализовать?
Просто для пояснения: в моем конкретном случае использования это будут использовать только программисты или люди, которые знают, что они делают. Это не файл конфигурации в программном обеспечении, которое будет распространяться среди конечных пользователей.
5 ответов
Лучший пример, который я могу придумать для этого, это Django settings.py
файл, но я уверен, что есть множество других примеров использования файла Python для конфигурации.
Есть несколько ключевых преимуществ использования Python в качестве конфигурационного файла по сравнению с другими решениями, например:
- Нет необходимости анализировать файл: поскольку файл уже является Python, вам не нужно писать или импортировать анализатор для извлечения пар ключ-значение из файла.
- Настройки конфигурации могут быть чем-то большим, чем просто ключ / значения: хотя было бы глупо, чтобы настройки определяли свои собственные классы, вы можете использовать их для определения кортежей, списков или словарей настроек, допускающих больше параметров и конфигурации, чем другие параметры. Это особенно верно для django, где файл настроек должен быть приспособлен для всех видов плагинов, которые изначально не были известны дизайнерам фреймворков.
- Написание файлов конфигурации очень просто: это ложно, но поскольку конфигурация представляет собой файл Python, ее можно редактировать и отлаживать в IDE самой программы.
- Неявная проверка ошибок: если вашей программе требуется параметр с именем
FILE_NAME
и это не в настройках программа выдаст исключение. Это означает, что настройки становятся обязательными, а обработка ошибок может быть более явной. Это может быть обоюдоострый меч, но изменение конфигурационных файлов вручную должно быть для опытных редакторов, которые должны быть в состоянии справиться с последствиями исключений. - Параметры конфигурации легко доступны и пространства имен: как только вы идете
import settings
ты можешь дико начать звонитьsettings.UI_COLOR
или жеsettings.TIMEOUT
, Это понятно, и с правильной IDE отслеживать, где эти настройки сделаны, становится проще, чем с плоскими файлами.
Но самая веская причина: переопределения, переопределения, переопределения. Это довольно сложная ситуация и может зависеть от конкретного случая использования, но в некоторых местах она поощряется django.
Представьте, что вы создаете веб-приложение, где есть сервер разработки и производства. Каждому из них нужны свои настройки, но 90% из них одинаковы. В этом случае вы можете сделать такие вещи, как определить файл конфигурации, который охватывает всю разработку, и сделать его (если это безопаснее) настройками по умолчанию, а затем переопределить его производство, например, так:
PORT = 8080
HOSTNAME = "dev.example.com"
COLOR = "0000FF"
if SITE_IS_LIVE:
import * from production_settings.py
Делать import * from
вызовет любые настройки, которые были объявлены в production_settings.py
файл для переопределения объявлений в файле настроек.
Я не видел рекомендаций по передовому опыту или документа PEP, в которых описано, как это сделать, но если вам нужны некоторые общие рекомендации, хорошим примером для подражания является django settings.py.
- Используйте согласованные имена переменных, предпочтительно UPPER CASE, поскольку они понимаются как параметры или константы.
- Ожидайте странные структуры данных, если вы используете Python в качестве языка конфигурации, то попробуйте обработать все основные типы данных.
- Не пытайтесь создать интерфейс для изменения настроек, это не простой текстовый редактор.
Когда не следует использовать этот подход? Когда вы имеете дело с простыми парами ключ / значение, которые должны быть изменены начинающими пользователями. Конфиги Python - это только для опытных пользователей. Начинающие пользователи забудут заканчивать кавычки или списки, будучи непоследовательными, удалят опции, которые, по их мнению, не применяются, будут фиксировать самые несвободные из них и будут смешивать только пробелы и табуляции Поскольку вы, по сути, имеете дело с кодом, а не с файлами конфигурации, все это сломает вашу программу. С другой стороны, написание инструмента, который будет анализировать через файл python, чтобы найти подходящие опции и обновить их, вероятно, доставит больше хлопот, чем стоит, и вам лучше будет повторно использовать существующий модуль, такой как ConfigParser
Я думаю, что код Python напрямую используется для конфигурации, главным образом потому, что это очень простой, быстрый, мощный и гибкий способ сделать это. В настоящее время в экосистеме Python нет другого инструмента, обеспечивающего все эти преимущества вместе. Cat ConfigParserShootout дает вам достаточно причин, почему может быть лучше накатить код Python как config.
Есть некоторые соображения безопасности, которые можно обойти либо с помощью защитной оценки кода, либо с помощью политик, таких как правильная установка разрешений файловой системы при развертывании.
Я видел так много борьбы с довольно сложной конфигурацией, выполняемой в различных форматах, с использованием различных синтаксических анализаторов, но, в конце концов, проще всего, когда это делается в коде.
Единственный реальный недостаток, с которым я столкнулся, это то, что люди, управляющие конфигурацией, должны быть немного осведомлены о Python, по крайней мере, о синтаксисе, чтобы иметь возможность что-либо делать и ничего не тормозить. Может или не имеет значения в каждом конкретном случае.
Также тот факт, что некоторые серьезные проекты, такие как Django и Sphinx, используют именно этот подход, должен быть достаточно утешительным:
Существует много вариантов написания конфигурационных файлов с хорошо написанными парсерами:
нет никаких веских причин для какой-либо конфигурации напрямую анализироваться как скрипт Python. Это может привести ко многим видам проблем, начиная с аспектов безопасности и заканчивая сложными отладочными ошибками, которые могут возникнуть в конце работы программы.
Там даже обсуждения, чтобы построить альтернативу setup.py
для пакетов Python, что довольно близко к конфигурации на основе исходного кода Python с точки зрения программиста Python.
В противном случае, вы, возможно, просто видели объекты Python, экспортируемые в виде строк, которые немного похожи на json, но немного более гибкие... Что в таком случае прекрасно, если вы этого не сделаете eval()
/ exec()
их или даже импортировать, но пропустить через анализатор, например , ast.literal_eval или parsing
, так что вы можете быть уверены, что загружаете только статические данные, а не исполняемый код.
Только несколько раз я понимаю, что что-то похожее на файл конфигурации, написанный на python, - это модуль, включенный в библиотеку, который определяет константы, используемые этой библиотекой, предназначенные для обработки пользователем библиотеки. Я даже не уверен, что это было бы хорошим дизайнерским решением, но я бы понял такую вещь.
редактировать:
Я бы не рассматривал файл settings.py в django как пример хорошей практики, хотя считаю, что это часть того, что я считаю файлом конфигурации для грамотных в кодировании пользователей, который отлично работает, потому что django нацелен на использование в основном программистами и системными администраторами. Кроме того, Django предлагает способ настройки через веб-страницу.
Чтобы принять аргументы @ lego:
- Нет необходимости разбирать файл
нет необходимости явно разбирать его, хотя стоимость синтаксического анализа анекдотична, даже больше, учитывая безопасность и дополнительную безопасность, а также способность обнаруживать проблемы на ранних этапах
- Настройки конфигурации могут быть больше, чем просто ключ / значения
Кроме ini-файлов, вы можете определить практически любой фундаментальный тип python, используя json / yaml или xml. И вы не хотите определять классы или создавать сложные объекты в файле конфигурации...
- Написание файлов конфигурации легко:
но с помощью хорошего редактора можно проверить и проверить синтаксис json / yaml или даже xml, чтобы получить идеально разбираемый файл.
- Неявная проверка ошибок:
это не аргумент, так как вы говорите, что это двойной поток, у вас может быть что-то, что хорошо разбирает, но вызывает исключение после многих часов работы.
- Параметры конфигурации легко доступны и пространства имен:
используя json / yaml или xml, параметры могут быть легко помещены в пространство имен и, естественно, использованы в качестве объектов python.
- Но самая веская причина: переопределения, переопределения, переопределения
Это не хороший аргумент ни в пользу кода Python. Учитывая, что ваш код состоит из нескольких модулей, которые являются взаимозависимыми и используют общий файл конфигурации, и каждый из них имеет свою собственную конфигурацию, тогда довольно просто сначала загрузить основной файл конфигурации как старый добрый словарь Python, а другие файлы конфигурации только что загружен обновлением словаря.
Если вы хотите отслеживать изменения, существует множество рецептов для организации иерархии диктов, которая откатывается к другой диктовке, если она не содержит значения.
И, наконец, значения конфигурации, измененные во время выполнения, нельзя (на самом деле не следует) сериализовать в Python правильно, так как это будет означать изменение текущей запущенной программы.
Я не говорю, что вы не должны использовать python для хранения переменных конфигурации, я просто говорю, что независимо от того, какой синтаксис вы выберете, вы должны получить его через анализатор, прежде чем получать его как экземпляры в вашей программе. Никогда, никогда не загружайте изменяемый пользователем контент без двойной проверки. Никогда не доверяйте своим пользователям!
Если люди из django делают это, то это потому, что они создали среду, которая имеет смысл только при объединении множества плагинов для создания приложения. А затем, чтобы настроить приложение, вы используете базу данных (которая является своего рода файлом конфигурации… на стероидах) или реальные файлы.
НТН
Я часто делал это во внутренних инструментах и играх компании. Основная причина простота: вы просто импортируете файл и вам не нужно заботиться о форматах или парсерах. Обычно это было именно то, что сказал @zmo, константы, которые должны были изменять непрограммисты в команде (скажем, размер сетки уровня игры или разрешение экрана).
Иногда полезно иметь логику в конфигурации. Например, альтернативные функции, которые заполняют начальную конфигурацию доски в игре. Я нашел это большое преимущество на самом деле.
Я признаю, что это может привести к трудностям при отладке. Возможно, в этих случаях эти модули были больше похожи на модули инициализации игрового уровня, чем на обычные конфигурационные файлы. Во всяком случае, я был очень рад простому способу создания четких текстовых конфигурационных файлов с возможностью иметь там логику и ни разу не получился.
Это еще один вариант файла конфигурации. Существует несколько вполне подходящих форматов конфигурационных файлов.
Пожалуйста, уделите немного времени, чтобы понять точку зрения системного администратора или стороннего поставщика, поддерживающего ваш продукт. Если есть еще один формат файла конфигурации, они могут отказаться от вашего продукта. Если у вас есть продукт, который имеет монументальное значение, тогда люди будут изучать синтаксис только для того, чтобы прочитать ваш файл конфигурации. (например, X.org или apache)
Если вы планируете доступ / запись информации о файле конфигурации на другом языке программирования, то файл конфигурации на основе Python будет плохой идеей.