Файл конфигурации со списком пар ключ-значение в Python - PullRequest
25 голосов
/ 09 октября 2008

У меня есть скрипт Python, который анализирует набор сообщений об ошибках и проверяет каждое сообщение, соответствует ли оно определенному шаблону (регулярному выражению), чтобы сгруппировать эти сообщения. Например, «файл x не существует» и «файл y не существует» будет соответствовать «file. * Не существует» и учитываться как два вхождения категории «файл не найден».

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

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

Есть ли у вас какие-либо идеи о том, что может быть хорошим способом для достижения этой цели?

Обновление: спасибо Дарену Томасу и Федерико Рампони, но у меня не может быть внешнего файла python с возможно произвольным кодом.

Ответы [ 6 ]

38 голосов
/ 09 октября 2008

Иногда я просто пишу модуль python (т.е. файл) с именем config.py или что-то со следующим содержимым:

config = {
    'name': 'hello',
    'see?': 'world'
}

тогда это можно «прочитать» следующим образом:

from config import config
config['name']
config['see?']

легко.

35 голосов
/ 09 октября 2008

У вас есть два достойных варианта:

  1. Стандартный формат файла конфигурации Python используя ConfigParser
  2. YAML с использованием такой библиотеки, как PyYAML

Стандартные файлы конфигурации Python выглядят как файлы INI с парами [sections] и key : value или key = value. Преимущества этого формата:

  • Сторонние библиотеки не нужны
  • Простой, знакомый формат файла.

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

file .* does not exist : file not found
user .* not found : authorization error

Или вот так:

{ file .* does not exist: file not found,
  user .* not found: authorization error }

Использование PyYAML не может быть проще:

import yaml

errors = yaml.load(open('my.yaml'))

На данный момент errors - это словарь Python в ожидаемом формате. YAML может представлять больше словарей: если вы предпочитаете список пар, используйте этот формат:

-
  - file .* does not exist 
  - file not found
-
  - user .* not found
  - authorization error

Или

[ [file .* does not exist, file not found],
  [user .* not found, authorization error]]

, который выдаст список списков при вызове yaml.load.

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

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

Любой из них звучит так, как будто он соответствует вашим текущим потребностям. С ConfigParser будет легче начинать, в то время как YAML даст вам большую гибкость в будущем, если ваши потребности расширятся.

Удачи!

8 голосов
/ 09 октября 2008

Я слышал, что с ConfigObj легче работать, чем с ConfigParser. Он используется многими крупными проектами, IPython, Trac, Turbogears и т. Д ...

Из их введения :

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

  • Вложенные разделы (подразделы) на любой уровень
  • Список значений
  • Многострочные значения
  • Строковая интерполяция (подстановка)
  • Интегрирован с мощной системой проверки
    • включая автоматическую проверку типа / преобразование
    • повторные разделы
    • и допустимые значения по умолчанию
  • При записи конфигурационных файлов ConfigObj сохраняет все комментарии и порядок членов и разделов
  • Множество полезных методов и опций для работы с файлами конфигурации (например, метод reload)
  • Полная поддержка Unicode
4 голосов
/ 09 октября 2008

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

<code>[
("file .* does not exist", "file not found"),
("user .* not authorized", "authorization error")
]
В вашем коде загрузите его, затем оцените и скомпилируйте регулярные выражения в результате:
<code>f = open("messages.py")
messages = eval(f.read()) # caution: you must be <em>sure</em> of what's in that file
f.close()
messages = [(re.compile(r), m) for (r,m) in messages]
и вы получите список кортежей (compiled_regexp, message).
4 голосов
/ 09 октября 2008

Я думаю, вам нужен модуль ConfigParser в стандартной библиотеке. Он читает и записывает файлы в стиле INI. Примеры и документация в стандартной документации, на которую я ссылаюсь, очень полны.

3 голосов
/ 09 октября 2008

Обычно я делаю то, что предложил Дарен, просто сделайте ваш конфигурационный файл скриптом Python:

patterns = {
    'file .* does not exist': 'file not found',
    'user .* not found': 'authorization error',
}

Тогда вы можете использовать его как:

import config

for pattern in config.patterns:
    if re.search(pattern, log_message):
        print config.patterns[pattern]

Кстати, именно это и делает Django со своим файлом настроек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...