Python создать файл настроек

Обновлено: 05.07.2024

Модуль ConfigParser в Python чрезвычайно важен для создания настраиваемых приложений.

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

Что может включать в себя ConfigParser?

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

Значения разделяются знаком = или (:).

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

Значения, которые могут использоваться программно в вышеуказанных файлах, – это URL-адрес, имя пользователя и пароль.

Файлы конфигурации

Давайте применим эти концепции к некоторым фрагментам кода.

Использование файлов

Мы создадим образец файла конфигурации, который выглядит следующим образом:

Создайте этот файл, назовите его database.config и храните в том же каталоге, что и программа, которую мы напишем следующей:

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

Пример configparser в python

На самом деле это было довольно просто.

Проверка наличия файла

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

Посмотрим фрагмент кода Python:

Посмотрим на результат этой программы:

Анализатор конфигурационных файлов

Перебор всех имеющихся значений

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

Давайте посмотрим во фрагменте кода, как это можно сделать:

Посмотрим на результат этой программы:

Конфигурационные файлы в python повторяют свойства

Проверка наличия раздела

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

Посмотрим на результат этой программы:

Раздел configparser

Проверка наличия значения

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

Посмотрим на результат этой программы:

Пример конфигурационного файла

Вывод

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


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

Совместимость с Python 3

Из за нововведений в стандарте PEP 8 модуль ConfigParser в Python 3 был переименован в configparser. Возможные ошибки:
ImportError: no module named ConfigParser

Решение проблемы совместимости

Создание файла

Создание файла config при помощи configparser невероятно просто. Давайте напишем небольшой код, чтобы посмотреть, как это работает:

Данный код создает файл config с одной секцией, под названием Settings, которая будет содержать наши опции: font, font_size, font_style и font_info. Обратите внимание на то, что в Python 3 нам нужно указать, что мы пишем файл в режиме write-only, или “w”. А в Python 2.7, мы использовали “wb” для написания в бинарном режиме.

Как читать, обновлять и удалять опции

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

Этот код сначала проверяет, существует ли файл config в принципе. Если его нет, то он использует созданную нами ранее функцию createConfig, чтобы создать файл. Далее мы создаем объект ConfigParser и указываем путь к файлу config для чтения. Чтобы прочесть опцию в вашем config файле, мы вызываем метод нашего объекта ConfigParser, указываем ему наименование секции и опции.

Есть вопросы по Python?

На нашем форуме вы можете задать любой вопрос и получить ответ от всего нашего сообщества!

Telegram Чат & Канал

Вступите в наш дружный чат по Python и начните общение с единомышленниками! Станьте частью большого сообщества!

Паблик VK

Одно из самых больших сообществ по Python в социальной сети ВК. Видео уроки и книги для вас!

Это вернет значение параметра. Если вы хотите изменить значение опции, вам нужно использовать метод set, в котором вы указываете название секции, опции, и новое значение. Наконец, мы можем использовать метод remove_option, чтобы удалить опцию. В нашем примере мы изменили значение font_size, и задали ему размер 12, затем мы удалили опцию font_style. После этого мы записали наши изменения на диск. Этот пример на на столько хорош, давайте упростим наш код. Для этого мы разделим наш код на на несколько функции:

Этот пример выглядит более организованно, по сравнению с первым. Я зашел так далеко, что назвал функции соответственно стандартам PEP8. Каждая функция должна объяснять сама себя и выполнять лишь одну задачу. Вместо того, чтобы помещать всю логику в одну единственную функцию, мы разделяем её на несколько функций, после чего демонстрируем их функционал в конце оператора if. Теперь вы можете импортировать модуль и использовать по назначению. Обратите внимание на то, что в этом примере есть сложная секция, так что вам, возможно, захочется усовершенствовать этот пример в дальнейшем, чтобы сделать его более универсальным.

Как использовать интерполяцию

Модуль configparser также подразумевает возможность интерполяции, что значит, что вы можете использовать существующие опции, для создания другой опции. Мы на самом деле это делали с опцией font_info, чьи параметры основаны на опциях font и font_size. Мы можем изменить интерполированное значение при помощи словаря Python. Давайте уделим несколько минут, и взглянем на оба случая.

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

Что такое файлы конфигурации в Python?

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

Ниже приведен пример конфигурационного файла, который состоит из трех разделов, а именно: Адрес, Образование и Хобби человека.

Теперь мы создадим вышеуказанный файл конфигурации с помощью модуля ConfigParser в python.

Как создать файл конфигурации с помощью модуля Python ConfigParser?

Для создания файла конфигурации на python мы будем использовать модуль configparser. В следующей реализации мы создаем объект ConfigParser и добавляем в него разделы, которые в основном являются словарями, содержащими пары ключ-значение. Затем мы сохраняем файл конфигурации с расширением .ini.

Вывод для приведенного выше фрагмента кода:

Как добавить новый раздел в конфигурационные файлы, созданные с помощью ConfigParser?

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

Вывод для приведенного выше фрагмента кода:

Мы также можем использовать метод add_section() для добавления нового раздела, а затем использовать метод set() для добавления новых полей в раздел.

В приведенном выше примере мы видим, что add_section() метод принимает имя раздела в качестве аргумента,в то время как set() метод принимает имя раздела в качестве первого аргумента, имя поля в качестве второго аргумента и значение поля в качестве третьего аргумента.

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

Как обновить данные в файлах конфигурации?

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

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

Как удалить данные из файла конфигурации?

Мы можем удалить данные из конфигурационных файлов с помощью remove_option() и remove_section() модуля в модуле configparser. remove_option() используется для удаления поля из любого раздела, а remove_section() используется для удаления полного раздела файла конфигурации.

В приведенном выше примере мы видим, что метод remove_option() принимает имя раздела в качестве первого аргумента и имя поля в качестве второго аргумента, тогда как метод remove_section() принимает имя раздела, подлежащего удалению, в качестве аргумента.

Вывод

В этом уроке мы рассмотрели, что такое файлы конфигурации, а также узнали, как создавать файлы конфигурации и управлять ими с помощью модуля Python configparser. Счастливого Обучения! 🙂


Вводные замечания о форматах конфигурационных файлов

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

К наиболее распространенным форматам конфигурационных файлов, которые находят применение в контексте управления приложениями на Python, можно отнести INI, JSON, TOML и YAML.
  • INI – самый простой формат из рассмотренных. С одной стороны чем проще читать конфигурационный файл, тем лучше, но с другой – файлы *.INI могут оперировать только одномерными структурами, т.е. структурами с простой одноуровневой иерархией. В большинстве прикладных задач, когда приходится иметь дело с моделями объектов, допускающих представление в виде списков, ассоциативных массивов и т.п., возможностей INI оказывается недостаточно.
  • JSON-файл выглядит как обычный словарь Python и может включать сложные иерархические зависимости, однако с точки зрения читаемости проигрывает и YAML, и TOML. Кроме того, JSON не поддерживает комментарии, а они часто могут значительно упростить сопровождение кода.
  • В отличие от предыдущих, формат TOML обладает несоизмеримой гибкостью и широтой арсенала поддерживаемых типов данных. TOML поддерживает простые пары «ключ-значение», массивы, классические и встроенные таблицы, массивы таблиц, булевы значения, а также локальные временные метки и временные метки со смещением.

Для сравнения рассмотрим одну и ту же модель объекта, описанного с помощью TOML и JSON.

Вот TOML-представление модели объекта:

А вот JSON-представление:

Синтаксические особенности JSON – избыточные фигурные и квадратные скобки – делают сложноструктурные JSON-файлы «размазанными».

Формат YAML обладает схожими с форматом TOML возможностями (в смысле гибкости представления моделей объектов и разнообразия поддерживаемых типов данных), но на сложных структурах выглядит компактнее.

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

Python-библиотеки для работы с конфигурационными файлами

Из всего многообразия предназначенных для работы с конфигурационными файлами библиотек – ориентированных на какой-то конкретный формат или «всеядных» – можно выделить следующие:

    : это элемент стандартной библиотеки Python, предназначенный для работы с INI-файлами Microsoft Windows. В распоряжении пользователя есть класс ConfigParser , который реализует базовые возможности библиотеки. : элемент не входит в стандартную библиотеку, поэтому его нужно установить с помощью менеджера пакетов pip pip install pyyaml . В Python-сценарии обращение к библиотеке выглядит как import yaml .
    : этот элемент тоже представляет собой стороннее решение для работы с форматом TOML и требует установки с помощью pip install toml . : это очень гибкая библиотека, которая 1) позволяет работать со всеми популярными форматами конфигурационных файлов (*.toml, *.yaml, *.json, *.ini, *.py), 2) поддерживает мультипрофили, т.е. конфигурационный файл может содержать несколько заголовков, относящихся к различным стадиям готовности программного продукта (например, default, development, production и т.д.), а нужный набор настроек затем вызывается с указанием соответствующего заголовка, 3) умеет работать с переменными окружения («работает из коробки» с библиотекой dotenv), 4) предлагает утилиту командной строки для выполнения операций общего назначения (init, list, write, validate и т.д.). Устанавливается библиотека с помощью менеджера пакетов pip pip install dynaconf .
    : это, строго говоря, не просто библиотека, а полноценная платформа, предназначенная для решения широкого круга задач, связанных с конфигурацией сложных приложений. Установить hydra можно либо с помощью менеджера пакетов pip pip install hydra-core --upgrade , либо с помощью менеджера пакетов conda conda install -c conda-forge hydra-core .

В основном, выбор библиотеки определяется следующими аспектами:

  • сложностью задачи и ее особенностями. К примеру, конфигурация маршрута подготовки моделей машинного обучения для развертывания на облачной платформе может быть выполнена и с помощью PyYAML/toml, а вот управление сложным web-проектом скорее всего потребует продвинутых возможностей dynaconf или hydra;
  • требованиями к показателю переиспользования кода. С этой точки зрения преимущества на стороне библиотеки hydra;
  • гибкостью решения и одновременно простотой сопровождения кода. Здесь чаще используются библиотеки PyYAML и toml.
Обобщая сказанное выше и учитывая класс задач, которые призваны решать конфигурационные файлы в контексте управления Python-приложениями, далее будем использовать YAML-файлы и библиотеку PyYAML.

Несколько слов о синтаксисе YAML

Синтаксис YAML прост и лаконичен, но есть несколько особенностей. Практически каждый YAML-файл строится на базе списка. Каждый элемент списка это список пар «ключ-значение», который обычно называют словарем. То есть представление модели объекта с помощью YAML сводится к тому, чтобы описать эту модель в терминах списков и словарей.

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

Все элементы списка располагаются на одном и том же уровне и начинаются с - (тире и пробел):

Словари YAML представляют собой, как в и Python, наборы пар «ключ-значение» (за двоеточием должен следовать пробел):

YAML поддерживает стандартные типы данных: целочисленный (int), вещественный (float), булев (boolean), строковый (string) и null:

При необходимости можно явно указывать тип данных значения с помощью конструкции !![тип данных] , например:

  • pi: !!float 3.14159 ,
  • flag: !!bool false и т.д.

Булевы значения, могут иметь разные варианты записи, но рекомендуется использовать true и false , чтобы YAML-файл был совместим с настройками по умолчанию большинства YAML-линтеров:

В YAML необязательно заключать строковые константы в кавычки, но в ситуациях, когда требуется явно подчеркнуть строковую природу значения, кавычки не помешают. Допускается использовать как одинарные, так и двойные кавычки. Единственное отличие заключается в том, что двойные кавычки разрешают использовать управляющие коды строковых констант – их еще называют экранированными последовательностями – \t (символ горизонтальной табуляции), \r (символ возврата каретки), \n (символ перехода на новую строку) и т.д.

Для работы с длинными строками используют символы | и >

Бывает, что отдельные фрагменты YAML-файла требуется повторить несколько раз. Для решения такого рода задач используются якоря & и псевдонимы * . Пример:

Псевдонимы можно задавать и для блоков:

С помощью ключа слияния <<: можно «наследовать» и переопределять разделы:

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

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

Проверка типов управляющих параметров конфигурационного файла

В простых сценариях использования, когда можно ограничиться контролем типа данных на уровне конфигурационного файла, будет достаточно использовать явное указание типа с помощью !![тип данных] .

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

Проверку типов можно организовать с помощью стандартной библиотеки Python dataclasses и сторонней библиотеки marshmallow_dataclass .

Рассмотрим простой пример использования marshmallow_dataclass, заимствованный со страницы проекта:

Здесь класс Building содержит всего два атрибута: вещественный height и строковый name . С помощью метода marshmallow.validate выполняется проверка на минимальное значение атрибута height , а с помощью field атрибут name получает значение по умолчанию.

Класс City содержит опциональный атрибут name , который ожидает получить либо объект строкового типа, либо None . Атрибут buildings ожидает принять список объектов типа Building .

Далее создаем экземпляр схемы city_schema на базе объекта класса City , а затем загружаем словарь. Схема ожидает получить строку для атрибута name и список объектов Building , то есть список объектов, которые описываются строковым атрибутом name и вещественными атрибутом height .

Используя точечную нотацию и нотацию списков можно добраться до значений атрибутов.

Шаблон применения конфигурационных файлов как инструмента управления Python-приложениями

Разобравшись с основными понятиями и концепциями, перейдем к рассмотрению связки «конфигурационный файл + Python-приложение».

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

Сильная сторона такого представления задачи заключается в возможности явным образом декомпозировать приложение на:

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

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

Этот шаблон распространяется на приложения произвольной сложности, но у него есть естественные ограничения.

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

В этом вопросе могут помочь:

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

Пример связки «конфигурационный YAML-файл + Python-приложение»

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

Для простоты гипотеза о выбросах проверяется с помощью классической стандартизованной Z-оценки и модифицированной робастной Z-оценки (англ.) на медиане. Для моделирования псевдослучайных процессов с гауссовским распределением ординат и корреляционными функциями заданного типа использовались алгоритмы, заимствованные из книги Быкова, В.В. «Цифровое моделирование в статистической радиотехнике» .

Полный код примера с пояснениями и деталями реализации доступен в github-репозитории .

Вот его структура:

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

В figure_examples хранятся демонстрационные примеры работы сценария python_scripts/main.py , а прямые результаты его работы в – каталоге figures .

Управлять типом корреляционной функции процесса можно с помощью параметра kind_acf . Смысл остальных управляющих параметров ( w_star , w0 , alpha и т.д.) должен быть понятен из комментариев.

Для запуска приложения следует перейти в корневой каталог проекта и выполнить:

Функция cmd_line_parser из модуля helper_funcs_and_class_schema.py прочитает значения флагов ( --config-path , --output-fig-path ), а затем вернет путь до конфигурационного файла и путь до файла с результатами анализа псевдослучайного процесса.

Затем, функция read_yaml_file прочитает конфигурационный файл и проверит типы управляющих параметров. Если типы управляющих параметров корректны и ошибок нет, то функция вернет объект типа Params , к атрибутам которого можно будет обратиться с помощью точечной нотации. Остается только построить сводку с использованием функции draw_graph .

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

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

Здесь sed ищет строку « w0: !!float 3.0 », заменяет ее строкой « w0: !!float 3.15 » и записывает результат ( > ) в новый конфигурационный файл.

На рисунках ниже приведены результаты работы Python-приложения с различными комбинациями управляющих параметров.

Сводка по анализу выбросов стационарного гауссовского псевдослучайного процесса с корреляционной функцией экспоненциального типа Сводка по анализу выбросов стационарного гауссовского псевдослучайного процесса с корреляционной функцией экспоненциально-косинусного типа Сводка по анализу выбросов стационарного гауссовского псевдослучайного процесса с корреляционной функцией экспоненциально-косинусно-синусного типа (минус) Сводка по анализу выбросов стационарного гауссовского псевдослучайного процесса с корреляционной функцией экспоненциально-косинусно-синусного типа (плюс)

Читайте также: