Автор оригинала: Doug Hellmann.
Цель:
Чтение/запись файлов конфигурации, аналогичных файлам Windows INI
Используйте модуль configparser
для управления редактируемыми пользователем файлами конфигурации приложения. Содержимое файлов конфигурации может быть организовано в группы, и поддерживается несколько типов значений параметров, включая целые числа, значения с плавающей запятой и логические значения. Значения параметров можно комбинировать с использованием строк форматирования Python для построения более длинных значений, таких как URL-адреса, из более коротких значений, таких как имена хостов и номера портов.
Формат файла конфигурации
Формат файла, используемый configparser
, аналогичен формату, используемому в более старых версиях Microsoft Windows. Он состоит из одного или нескольких именованных разделов , каждый из которых может содержать отдельные параметры с именами и значениями.
Разделы файла конфигурации идентифицируются поиском строк, начинающихся с [
и заканчивающихся ]
. Значение в квадратных скобках представляет собой имя раздела и может содержать любые символы, кроме квадратных скобок.
Параметры перечислены по одной в каждой строке в разделе. Строка начинается с имени параметра, которое отделяется от значения двоеточием (:
) или знаком равенства (
). Пробелы вокруг разделителя игнорируются при анализе файла.
Строки, начинающиеся с точки с запятой (;
) или octothorpe ( #
), обрабатываются как комментарии и не отображаются при программном доступе к содержимому файла конфигурации.
В этом образце файла конфигурации есть раздел с именем bug_tracker
с тремя параметрами: url
, имя пользователя
и пароль
.
# This is a simple example with comments. [bug_tracker] url http://localhost:8080/bugs/ username dhellmann ; You should not store passwords in plain text ; configuration files. password SECRET
Чтение файлов конфигурации
Чаще всего файл конфигурации используется для того, чтобы пользователь или системный администратор отредактировал файл с помощью обычного текстового редактора, чтобы установить параметры поведения приложения по умолчанию, а затем попросить приложение прочитать файл, проанализировать его и действовать на основе его содержимого. Используйте метод read ()
в ConfigParser
, чтобы прочитать файл конфигурации.
configparser_read.py
from configparser import ConfigParser parser ConfigParser() parser.read('simple.ini') print(parser.get('bug_tracker', 'url'))
Эта программа считывает файл simple.ini
из предыдущего раздела и печатает значение параметра url
из раздела bug_tracker
.
$ python3 configparser_read.py http://localhost:8080/bugs/
Метод read ()
также принимает список имен файлов. Каждое имя по очереди сканируется, и если файл существует, он открывается и читается.
configparser_read_many.py
from configparser import ConfigParser import glob parser ConfigParser() candidates ['does_not_exist.ini', 'also-does-not-exist.ini', 'simple.ini', 'multisection.ini'] found parser.read(candidates) missing set(candidates) - set(found) print('Found config files:', sorted(found)) print('Missing files :', sorted(missing))
read ()
возвращает список, содержащий имена успешно загруженных файлов, поэтому программа может обнаружить, какие файлы конфигурации отсутствуют, и решить, игнорировать ли их или рассматривать условие как ошибку.
$ python3 configparser_read_many.py Found config files: ['multisection.ini', 'simple.ini'] Missing files : ['also-does-not-exist.ini', 'does_not_exist.ini']
Данные конфигурации Unicode
Файлы конфигурации, содержащие данные Unicode, следует читать с использованием правильного значения кодировки. В следующем примере файл изменяет значение пароля исходного ввода, чтобы он содержал символы Юникода и кодируется с использованием UTF-8.
unicode.ini
[bug_tracker] url = http://localhost:8080/bugs/ username = dhellmann password = ßéç®é†
Файл открывается с помощью соответствующего декодера, преобразующего данные UTF-8 в собственные строки Unicode.
configparser_unicode.py
from configparser import ConfigParser import codecs parser ConfigParser() # Open the file with the correct encoding parser.read('unicode.ini', encoding'utf-8') password parser.get('bug_tracker', 'password') print('Password:', password.encode('utf-8')) print('Type :', type(password)) print('repr() :', repr(password))
Значение, возвращаемое функцией get ()
, является строкой Unicode, поэтому для ее безопасной печати ее необходимо перекодировать в UTF-8.
$ python3 configparser_unicode.py Password: b'\xc3\x9f\xc3\xa9\xc3\xa7\xc2\xae\xc3\xa9\xe2\x80\xa0 ' Type :repr() : 'ßéç®é†'
Доступ к настройкам конфигурации
ConfigParser
включает методы для изучения структуры проанализированной конфигурации, включая перечисление разделов и параметров и получение их значений. Этот файл конфигурации включает два раздела для отдельных веб-служб.
[bug_tracker] url http://localhost:8080/bugs/ username dhellmann password SECRET [wiki] url http://localhost:8080/wiki/ username dhellmann password SECRET
В этом примере программы используются некоторые методы для просмотра данных конфигурации, включая section ()
, options ()
и items ()
.
configparser_structure.py
from configparser import ConfigParser parser ConfigParser() parser.read('multisection.ini') for section_name in parser.sections(): print('Section:', section_name) print(' Options:', parser.options(section_name)) for name, value in parser.items(section_name): print(' {} = {}'.format(name, value)) print()
И section ()
, и options ()
возвращают списки строк, а items ()
возвращает список кортежей, содержащих пары имя-значение.
$ python3 configparser_structure.py Section: bug_tracker Options: ['url', 'username', 'password'] url = http://localhost:8080/bugs/ username = dhellmann password = SECRET Section: wiki Options: ['url', 'username', 'password'] url = http://localhost:8080/wiki/ username = dhellmann password = SECRET
ConfigParser
также поддерживает тот же API сопоставления, что и dict , при этом ConfigParser
действует как один словарь, содержащий отдельные словари для каждого раздела.
configparser_structure_dict.py
from configparser import ConfigParser parser ConfigParser() parser.read('multisection.ini') for section_name in parser: print('Section:', section_name) section parser[section_name] print(' Options:', list(section.keys())) for name in section: print(' {} = {}'.format(name, section[name])) print()
Использование API сопоставления для доступа к одному и тому же файлу конфигурации дает тот же результат.
$ python3 configparser_structure_dict.py Section: DEFAULT Options: [] Section: bug_tracker Options: ['url', 'username', 'password'] url = http://localhost:8080/bugs/ username = dhellmann password = SECRET Section: wiki Options: ['url', 'username', 'password'] url = http://localhost:8080/wiki/ username = dhellmann password = SECRET
Проверка наличия ценностей
Чтобы проверить, существует ли раздел, используйте has_section ()
, передав имя раздела.
configparser_has_section.py
from configparser import ConfigParser parser ConfigParser() parser.read('multisection.ini') for candidate in ['wiki', 'bug_tracker', 'dvcs']: print('{:<12}: {}'.format( candidate, parser.has_section(candidate)))
Проверка наличия раздела перед вызовом get ()
позволяет избежать исключений для отсутствующих данных.
$ python3 configparser_has_section.py wiki : True bug_tracker : True dvcs : False
Используйте has_option ()
, чтобы проверить, существует ли параметр в разделе.
configparser_has_option.py
from configparser import ConfigParser parser ConfigParser() parser.read('multisection.ini') SECTIONS ['wiki', 'none'] OPTIONS ['username', 'password', 'url', 'description'] for section in SECTIONS: has_section parser.has_section(section) print('{} section exists: {}'.format(section, has_section)) for candidate in OPTIONS: has_option parser.has_option(section, candidate) print('{}.{:<12} : {}'.format( section, candidate, has_option)) print()
Если раздел не существует, has_option ()
возвращает False
.
$ python3 configparser_has_option.py wiki section exists: True wiki.username : True wiki.password : True wiki.url : True wiki.description : False none section exists: False none.username : False none.password : False none.url : False none.description : False
Типы значений
Все имена разделов и параметров обрабатываются как строки, но значения параметров могут быть строками, целыми числами, числами с плавающей запятой или логическими значениями. Существует ряд возможных логических значений, которые преобразуются в истинное или ложное. В следующем примере файла есть по одному.
types.ini
[ints] positive 1 negative -5 [floats] positive 0.2 negative -3.14 [booleans] number_true 1 number_false 0 yn_true yes yn_false no tf_true true tf_false false onoff_true on onoff_false false
ConfigParser
не пытается понять тип параметра. Ожидается, что приложение будет использовать правильный метод для получения значения желаемого типа. get ()
всегда возвращает строку. Используйте getint ()
для целых чисел, getfloat ()
для чисел с плавающей запятой и getboolean ()
для логических значений.
configparser_value_types.py
from configparser import ConfigParser parser ConfigParser() parser.read('types.ini') print('Integers:') for name in parser.options('ints'): string_value parser.get('ints', name) value parser.getint('ints', name) print(' {:<12} : {!r:<7} -> {}'.format( name, string_value, value)) print('\nFloats:') for name in parser.options('floats'): string_value parser.get('floats', name) value parser.getfloat('floats', name) print(' {:<12} : {!r:<7} -> {:0.2f}'.format( name, string_value, value)) print('\nBooleans:') for name in parser.options('booleans'): string_value parser.get('booleans', name) value parser.getboolean('booleans', name) print(' {:<12} : {!r:<7} -> {}'.format( name, string_value, value))
Запуск этой программы с примером ввода дает следующий результат.
$ python3 configparser_value_types.py Integers: positive : '1' -> 1 negative : '-5' -> -5 Floats: positive : '0.2' -> 0.20 negative : '-3.14' -> -3.14 Booleans: number_true : '1' -> True number_false : '0' -> False yn_true : 'yes' -> True yn_false : 'no' -> False tf_true : 'true' -> True tf_false : 'false' -> False onoff_true : 'on' -> True onoff_false : 'false' -> False
Конвертеры пользовательских типов можно добавить, передав функции преобразования в аргументе converters
в ConfigParser
. Каждый преобразователь получает одно входное значение и должен преобразовать это значение в соответствующий тип возврата.
configparser_custom_types.py
from configparser import ConfigParser import datetime def parse_iso_datetime(s): print('parse_iso_datetime({!r})'.format(s)) return datetime.datetime.strptime(s, '%Y-%m-%dT%H:%M:%S.%f') parser ConfigParser( converters{ 'datetime': parse_iso_datetime, } ) parser.read('custom_types.ini') string_value parser['datetimes']['due_date'] value parser.getdatetime('datetimes', 'due_date') print('due_date : {!r} -> {!r}'.format(string_value, value))
Добавление преобразователя приводит к тому, что ConfigParser
автоматически создает метод извлечения для этого типа с использованием имени типа, указанного в преобразователях
. В этом примере преобразователь 'datetime'
вызывает добавление нового метода getdatetime ()
.
$ python3 configparser_custom_types.py parse_iso_datetime('2015-11-08T11:30:05.905898') due_date : '2015-11-08T11:30:05.905898' -> datetime.datetime(201 5, 11, 8, 11, 30, 5, 905898)
Также возможно добавить методы конвертера непосредственно в подкласс ConfigParser
.
Параметры как флаги
Обычно синтаксическому анализатору требуется явное значение для каждого параметра, но если для параметра ConfigParser
allow_no_value
установлено значение True
, параметр может появляться сам по себе в строку во входном файле и использовать ее как флаг.
configparser_allow_no_value.py
import configparser # Require values try: parser configparser.ConfigParser() parser.read('allow_no_value.ini') except configparser.ParsingError as err: print('Could not parse:', err) # Allow stand-alone option names print('\nTrying again with) parser configparser.ConfigParser(allow_no_valueTrue) parser.read('allow_no_value.ini') for flag in ['turn_feature_on', 'turn_other_feature_on']: print('\n', flag) exists parser.has_option('flags', flag) print(' has_option:', exists) if exists: print(' get:', parser.get('flags', flag))
Если параметр не имеет явного значения, has_option ()
сообщает, что параметр существует, а get ()
возвращает None
.
$ python3 configparser_allow_no_value.py Could not parse: Source contains parsing errors: 'allow_no_value.ini' [line 2]: 'turn_feature_on\n' Trying again with turn_feature_on has_option: True get: None turn_other_feature_on has_option: False
Многострочные струны
Строковые значения могут занимать несколько строк, если последующие строки имеют отступ.
[example] message This is a multi-line string. With two paragraphs. They are separated by a completely empty line.
В многострочных значениях с отступом пустые строки рассматриваются как часть значения и сохраняются.
$ python3 configparser_multiline.py This is a multi-line string. With two paragraphs. They are separated by a completely empty line.
Изменение настроек
Хотя ConfigParser
в первую очередь предназначен для настройки путем чтения параметров из файлов, параметры также можно заполнить, вызвав add_section ()
для создания нового раздела и set ( )
, чтобы добавить или изменить параметр.
configparser_populate.py
import configparser parser configparser.ConfigParser() parser.add_section('bug_tracker') parser.set('bug_tracker', 'url', 'http://localhost:8080/bugs') parser.set('bug_tracker', 'username', 'dhellmann') parser.set('bug_tracker', 'password', 'secret') for section in parser.sections(): print(section) for name, value in parser.items(section): print(' {} = {!r}'.format(name, value))
Все параметры должны быть заданы как строки, даже если они будут извлечены как целые числа, значения с плавающей запятой или логические значения.
$ python3 configparser_populate.py bug_tracker url = 'http://localhost:8080/bugs' username = 'dhellmann' password = 'secret'
Разделы и параметры можно удалить из ConfigParser
с помощью remove_section ()
и remove_option ()
.
configparser_remove.py
from configparser import ConfigParser parser ConfigParser() parser.read('multisection.ini') print('Read values:\n') for section in parser.sections(): print(section) for name, value in parser.items(section): print(' {} = {!r}'.format(name, value)) parser.remove_option('bug_tracker', 'password') parser.remove_section('wiki') print('\nModified values:\n') for section in parser.sections(): print(section) for name, value in parser.items(section): print(' {} = {!r}'.format(name, value))
При удалении раздела удаляются все содержащиеся в нем параметры.
$ python3 configparser_remove.py Read values: bug_tracker url = 'http://localhost:8080/bugs/' username = 'dhellmann' password = 'SECRET' wiki url = 'http://localhost:8080/wiki/' username = 'dhellmann' password = 'SECRET' Modified values: bug_tracker url = 'http://localhost:8080/bugs/' username = 'dhellmann'
Сохранение файлов конфигурации
После заполнения ConfigParser
необходимыми данными его можно сохранить в файл, вызвав метод write ()
. Это позволяет предоставить пользовательский интерфейс для редактирования параметров конфигурации без необходимости писать какой-либо код для управления файлом.
configparser_write.py
import configparser import sys parser configparser.ConfigParser() parser.add_section('bug_tracker') parser.set('bug_tracker', 'url', 'http://localhost:8080/bugs') parser.set('bug_tracker', 'username', 'dhellmann') parser.set('bug_tracker', 'password', 'secret') parser.write(sys.stdout)
Метод write ()
принимает в качестве аргумента файловый объект. Он записывает данные в формате INI, чтобы их можно было снова проанализировать с помощью ConfigParser
.
$ python3 configparser_write.py [bug_tracker] url = http://localhost:8080/bugs username = dhellmann password = secret
Предупреждение
Комментарии в исходном файле конфигурации не сохраняются при чтении, изменении и перезаписи файла конфигурации.
Путь поиска вариантов
ConfigParser
использует многоэтапный процесс поиска при поиске варианта.
Перед запуском поиска опции проверяется название раздела. Если раздел не существует и имя не является специальным значением DEFAULT
, возникает ошибка NoSectionError
.
- Е
- с
- л
- и
- и
- м
- я
- п
- а
- р
- а
- м
- е
- т
- р
- а
- п
- о
- я
- в
- л
- я
- е
- т
- с
- я
- в
- с
- л
- о
- в
- а
- р
- е
- <
- c
- o
- d
- e
- >
- v
- a
- r
- s
- <
- /
- c
- o
- d
- e
- >
- ,
- п
- е
- р
- е
- д
- а
- н
- н
- о
- м
- в
- <
- c
- o
- d
- e
- >
- g
- e
- t
- (
- )
- <
- /
- c
- o
- d
- e
- >
- ,
- в
- о
- з
- в
- р
- а
- щ
- а
- е
- т
- с
- я
- з
- н
- а
- ч
- е
- н
- и
- е
- и
- з
- <
- c
- o
- d
- e
- >
- v
- a
- r
- s
- <
- /
- c
- o
- d
- e
- >
- .
- Е
- с
- л
- и
- и
- м
- я
- п
- а
- р
- а
- м
- е
- т
- р
- а
- п
- о
- я
- в
- л
- я
- е
- т
- с
- я
- в
- у
- к
- а
- з
- а
- н
- н
- о
- м
- р
- а
- з
- д
- е
- л
- е
- ,
- в
- о
- з
- в
- р
- а
- щ
- а
- е
- т
- с
- я
- з
- н
- а
- ч
- е
- н
- и
- е
- и
- з
- э
- т
- о
- г
- о
- р
- а
- з
- д
- е
- л
- а
- .
- Е
- с
- л
- и
- и
- м
- я
- п
- а
- р
- а
- м
- е
- т
- р
- а
- о
- т
- о
- б
- р
- а
- ж
- а
- е
- т
- с
- я
- в
- р
- а
- з
- д
- е
- л
- е
- <
- c
- o
- d
- e
- >
- D
- E
- F
- A
- U
- L
- T
- <
- /
- c
- o
- d
- e
- >
- ,
- в
- о
- з
- в
- р
- а
- щ
- а
- е
- т
- с
- я
- э
- т
- о
- з
- н
- а
- ч
- е
- н
- и
- е
- .
- Е
- с
- л
- и
- и
- м
- я
- п
- а
- р
- а
- м
- е
- т
- р
- а
- о
- т
- о
- б
- р
- а
- ж
- а
- е
- т
- с
- я
- в
- с
- л
- о
- в
- а
- р
- е
- <
- c
- o
- d
- e
- >
- d
- e
- f
- a
- u
- l
- t
- s
- <
- /
- c
- o
- d
- e
- >
- ,
- п
- е
- р
- е
- д
- а
- н
- н
- о
- м
- к
- о
- н
- с
- т
- р
- у
- к
- т
- о
- р
- у
- ,
- в
- о
- з
- в
- р
- а
- щ
- а
- е
- т
- с
- я
- э
- т
- о
- з
- н
- а
- ч
- е
- н
- и
- е
- .
Если имя не найдено ни в одном из этих расположений, возникает ошибка NoOptionError
.
С помощью этого файла конфигурации можно продемонстрировать поведение пути поиска.
[DEFAULT] file-only value from DEFAULT section init-and-file value from DEFAULT section from-section value from DEFAULT section from-vars value from DEFAULT section [sect] section-only value from section in file from-section value from section in file from-vars value from section in file
Эта тестовая программа включает настройки по умолчанию для параметров, не указанных в файле конфигурации, и отменяет некоторые значения, определенные в файле.
configparser_defaults.py
import configparser # Define the names of the options option_names [ 'from-default', 'from-section', 'section-only', 'file-only', 'init-only', 'init-and-file', 'from-vars', ] # Initialize the parser with some defaults DEFAULTS { 'from-default': 'value from defaults passed to init', 'init-only': 'value from defaults passed to init', 'init-and-file': 'value from defaults passed to init', 'from-section': 'value from defaults passed to init', 'from-vars': 'value from defaults passed to init', } parser configparser.ConfigParser(defaultsDEFAULTS) print('Defaults before loading file:') defaults parser.defaults() for name in option_names: if name in defaults: print(' {:<15} = {!r}'.format(name, defaults[name])) # Load the configuration file parser.read('with-defaults.ini') print('\nDefaults after loading file:') defaults parser.defaults() for name in option_names: if name in defaults: print(' {:<15} = {!r}'.format(name, defaults[name])) # Define some local overrides vars {'from-vars': 'value from vars'} # Show the values of all the options print('\nOption lookup:') for name in option_names: value parser.get('sect', name, varsvars) print(' {:<15} = {!r}'.format(name, value)) # Show error messages for options that do not exist print('\nError cases:') try: print('No such option :', parser.get('sect', 'no-option')) except configparser.NoOptionError as err: print(err) try: print('No such section:', parser.get('no-sect', 'no-option')) except configparser.NoSectionError as err: print(err)
В выходных данных показано происхождение значения каждой опции и показано, как значения по умолчанию из разных источников переопределяют существующие значения.
$ python3 configparser_defaults.py Defaults before loading file: from-default = 'value from defaults passed to init' from-section = 'value from defaults passed to init' init-only = 'value from defaults passed to init' init-and-file = 'value from defaults passed to init' from-vars = 'value from defaults passed to init' Defaults after loading file: from-default = 'value from defaults passed to init' from-section = 'value from DEFAULT section' file-only = 'value from DEFAULT section' init-only = 'value from defaults passed to init' init-and-file = 'value from DEFAULT section' from-vars = 'value from DEFAULT section' Option lookup: from-default = 'value from defaults passed to init' from-section = 'value from section in file' section-only = 'value from section in file' file-only = 'value from DEFAULT section' init-only = 'value from defaults passed to init' init-and-file = 'value from DEFAULT section' from-vars = 'value from vars' Error cases: No option 'no-option' in section: 'sect' No section: 'no-sect'
Комбинирование значений с интерполяцией
ConfigParser
предоставляет функцию, называемую интерполяцией , которую можно использовать для объединения значений вместе. Значения, содержащие строки стандартного формата Python, запускают функцию интерполяции при их извлечении. Параметры, названные в пределах извлекаемого значения, по очереди заменяются своими значениями до тех пор, пока подстановка не отпадет.
Примеры URL, приведенные ранее в этом разделе, можно переписать, чтобы использовать интерполяцию, чтобы упростить изменение только части значения. Например, этот файл конфигурации отделяет протокол, имя хоста и порт от URL-адреса как отдельные параметры.
[bug_tracker] protocol http server localhost port 8080 url %(protocol)s://%(server)s:%(port)s/bugs/ username dhellmann password SECRET
По умолчанию интерполяция выполняется каждый раз при вызове get ()
. Передайте истинное значение в аргументе raw
, чтобы получить исходное значение без интерполяции.
configparser_interpolation.py
from configparser import ConfigParser parser ConfigParser() parser.read('interpolation.ini') print('Original value :', parser.get('bug_tracker', 'url')) parser.set('bug_tracker', 'port', '9090') print('Altered port value :', parser.get('bug_tracker', 'url')) print('Without interpolation:', parser.get('bug_tracker', 'url', rawTrue))
Поскольку значение вычисляется с помощью get ()
, изменение одной из настроек, используемых значением url
, изменяет возвращаемое значение.
$ python3 configparser_interpolation.py Original value : http://localhost:8080/bugs/ Altered port value : http://localhost:9090/bugs/ Without interpolation: %(protocol)s://%(server)s:%(port)s/bugs/
Использование значений по умолчанию
Значения для интерполяции не обязательно должны появляться в том же разделе, что и исходный вариант. Значения по умолчанию можно смешивать со значениями переопределения.
[DEFAULT] url %(protocol)s://%(server)s:%(port)s/bugs/ protocol http server bugs.example.com port 80 [bug_tracker] server localhost port 8080 username dhellmann password SECRET
В этой конфигурации значение для url
поступает из раздела DEFAULT
, и подстановка начинается с просмотра bug_tracker
и возврата к ПО УМОЛЧАНИЮ
для частей, которые не найдены.
configparser_interpolation_defaults.py
from configparser import ConfigParser parser ConfigParser() parser.read('interpolation_defaults.ini') print('URL:', parser.get('bug_tracker', 'url'))
Значения hostname
и port
взяты из раздела bug_tracker
, а protocol
– из DEFAULT .
$ python3 configparser_interpolation_defaults.py URL: http://localhost:8080/bugs/
Ошибки замены
Замена прекращается после шагов MAX_INTERPOLATION_DEPTH
, чтобы избежать проблем из-за рекурсивных ссылок.
configparser_interpolation_recursion.py
import configparser parser configparser.ConfigParser() parser.add_section('sect') parser.set('sect', 'opt', '%(opt)s') try: print(parser.get('sect', 'opt')) except configparser.InterpolationDepthError as err: print('ERROR:', err)
Исключение InterpolationDepthError
возникает, если шагов подстановки слишком много.
$ python3 configparser_interpolation_recursion.py ERROR: Recursion limit exceeded in value substitution: option 'o pt' in section 'sect' contains an interpolation key which cannot be substituted in 10 steps. Raw value: '%(opt)s'
Отсутствующие значения приводят к исключению InterpolationMissingOptionError
.
configparser_interpolation_error.py
import configparser parser configparser.ConfigParser() parser.add_section('bug_tracker') parser.set('bug_tracker', 'url', 'http://%(server)s:%(port)s/bugs') try: print(parser.get('bug_tracker', 'url')) except configparser.InterpolationMissingOptionError as err: print('ERROR:', err)
Поскольку значение server
не определено, url
не может быть создан.
$ python3 configparser_interpolation_error.py ERROR: Bad value substitution: option 'url' in section 'bug_tracker' contains an interpolation key 'server' which is not a valid option name. Raw value: 'http://%(server)s:%(port)s/bugs'
Экранирование специальных символов
Поскольку %
запускает инструкции интерполяции, буквальный %
в значении должен быть экранирован как %%
.
[escape] value a literal %% must be escaped
Считывание значения не требует особого внимания.
configparser_escape.py
from configparser import ConfigParser import os filename 'escape.ini' config ConfigParser() config.read([filename]) value config.get('escape', 'value') print(value)
Когда значение считывается, %%
автоматически преобразуется в %
.
$ python3 configparser_escape.py a literal % must be escaped
Расширенная интерполяция
ConfigParser
поддерживает альтернативные реализации интерполяции. Передача объекта, который поддерживает API, определенный параметром Interpolation
, в параметр interpolation
. Например, использование ExtendedInterpolation
вместо BasicInterpolation
по умолчанию позволяет использовать другой синтаксис с использованием $ {}
для указания переменных.
configparser_extendedinterpolation.py
from configparser import ConfigParser, ExtendedInterpolation parser ConfigParser(interpolationExtendedInterpolation()) parser.read('extended_interpolation.ini') print('Original value :', parser.get('bug_tracker', 'url')) parser.set('intranet', 'port', '9090') print('Altered port value :', parser.get('bug_tracker', 'url')) print('Without interpolation:', parser.get('bug_tracker', 'url', rawTrue))
Расширенная интерполяция поддерживает доступ к значениям из других разделов файла конфигурации путем добавления к имени переменной префикса имени раздела и двоеточия (:
).
[intranet] server = localhost port = 8080 [bug_tracker] url = http://${intranet:server}:${intranet:port}/bugs/ username = dhellmann password = SECRET
Обращение к значениям в других разделах файла позволяет совместно использовать иерархию значений, не помещая все значения по умолчанию в раздел DEFAULTS
.
$ python3 configparser_extendedinterpolation.py Original value : http://localhost:8080/bugs/ Altered port value : http://localhost:9090/bugs/ Without interpolation: http://${intranet:server}:${intranet:port }/bugs/
Отключение интерполяции
Чтобы отключить интерполяцию, передайте None
вместо объекта Interpolation
.
configparser_nointerpolation.py
from configparser import ConfigParser parser ConfigParser(interpolationNone) parser.read('interpolation.ini') print('Without interpolation:', parser.get('bug_tracker', 'url'))
Это позволяет безопасно игнорировать любой синтаксис, который мог быть обработан объектом интерполяции.
$ python3 configparser_nointerpolation.py Without interpolation: %(protocol)s://%(server)s:%(port)s/bugs/
Смотрите также
- стандартная библиотечная документация для configparser
- ConfigObj – расширенный синтаксический анализатор файла конфигурации с поддержкой таких функций, как проверка содержимого.
- Замечания по переносу Python 2 на 3 для configparser