Fichier de Configuration avec liste des paires clé-valeur en python

J'ai un script python qui analyse un ensemble de messages d'erreur et vérifie pour chaque message si elle correspond à un certain modèle (expression régulière) afin de regrouper ces messages. Par exemple "fichier x n'existe pas" et "fichier y n'existe pas" pourrait correspondre à "fichier .* n'existe pas" et être comptabilisé comme deux occurrences de la catégorie" Fichier introuvable".

Comme le nombre de modèles et de catégories augmente, je voudrais mettre ces couples "expression régulière / chaîne d'affichage" dans un fichier de configuration, essentiellement une sérialisation de dictionnaire de quelque sorte.

Je voudrais que ce fichier soit modifiable à la main, donc je rejette toute forme de sérialisation binaire, et aussi je préfère ne pas recourir à la sérialisation xml pour éviter les problèmes avec les caractères à échapper (& et ainsi de suite...).

Avez-vous une idée de ce qui pourrait être un bon moyen d'y parvenir?

Mise à jour: merci à Daren Thomas et Federico Ramponi, mais je ne peux pas avoir un fichier Python externe avec code éventuellement arbitraire.

25
demandé sur Mike Pennington 2008-10-09 15:55:48

6 réponses

Vous avez deux options décentes:

  1. format de fichier de configuration standard Python utilisation de ConfigParser
  2. YAML en utilisant une bibliothèque comme PyYAML

Les fichiers de configuration Python standard ressemblent à des fichiers INI avec des paires [sections] et key : value ou key = value. Les avantages de ce format sont:

  • Pas de bibliothèques tierces nécessaires
  • format de fichier simple et familier.

YAML est différent en ce qu'il est conçu pour être un format de sérialisation de données convivial humain plutôt que spécifiquement conçu pour la configuration. Il est très lisible et vous donne deux façons différentes de représenter les mêmes données. Pour votre problème, vous pouvez créer un fichier YAML qui ressemble à ceci:

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

Ou comme ceci:

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

Utiliser PyYAML ne pouvait pas être plus simple:

import yaml

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

À ce stade errors est un dictionnaire Python avec le format attendu. YAML est capable de représenter plus que des dictionnaires: si vous préférez une liste de paires, utilisez ce format:

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

Ou

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

Qui produira une liste de listes lorsque yaml.load est appelé.

Un avantage de YAML est que vous pouvez l'utiliser pour exporter vos données existantes codées en dur dans un fichier pour créer la version initiale, plutôt que de couper / coller plus un tas de rechercher / remplacer pour obtenir les données dans le bon format.

Le format YAML prendra un peu plus de temps à se familiariser, mais l'utilisation de PyYAML est encore plus simple que D'utiliser ConfigParser avec L'avantage est que vous avez plus d'options concernant la façon dont vos données sont représentées en utilisant YAML.

L'un ou l'autre semble correspondre à vos besoins actuels, ConfigParser sera plus facile à démarrer tandis que YAML vous donnera plus de flexibilité à l'avenir, si vos besoins se développent.

Bonne chance!

35
répondu Aaron Hays 2008-10-09 14:57:08

Parfois, j'écris simplement un module python (c'est-à-dire un fichier) appelé config.py ou quelque chose avec le contenu suivant:

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

Cela peut alors être ' lu ' comme ceci:

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

Doucement.

37
répondu Daren Thomas 2008-10-09 12:32:37

J'ai entendu dire que ConfigObj est plus facile à utiliser que ConfigParser. Il est utilisé par beaucoup de grands projets, IPython, Trac, Turbogears, etc...

À Partir de leur introduction:

ConfigObj est un simple mais puissant lecteur de fichier de configuration et écrivain: un fichier ini round tripper. Sa principale caractéristique est qu'il est très facile à utiliser, avec une interface de programmeur simple et une syntaxe simple pour les fichiers de configuration. Il a beaucoup d'autres fonctionnalités bien :

  • sections imbriquées (sous-sections), à n'importe quel niveau
  • valeurs de Liste
  • Plusieurs valeurs de ligne
  • interpolation de chaîne (substitution)
  • intégré à un puissant système de validation
    • y compris la vérification/conversion automatique du type
    • sections répétées
    • et autoriser les valeurs par défaut
  • lors de l'écriture de fichiers de configuration, ConfigObj conserve tous les commentaires et l'ordre des membres et les sections
  • de nombreuses méthodes et options utiles pour travailler avec les fichiers de configuration (comme la méthode 'reload')
  • prise en charge complète de L'Unicode
8
répondu sheats 2008-10-09 12:21:25

Je pense que vous voulez le module ConfigParser dans la bibliothèque standard. Il lit et écrit des fichiers de style INI. Les exemples et la documentation dans la documentation standard à laquelle j'ai lié sont très complets.

4
répondu Andrew Wilkinson 2008-10-09 12:00:52

Si vous êtes le seul à avoir accès au fichier de configuration, vous pouvez utiliser une solution simple et de bas niveau. Garder le "dictionnaire" dans un fichier texte comme une liste de tuples (regexp, message), exactement comme si c'était une expression python:

[
("file .* does not exist", "file not found"),
("user .* not authorized", "authorization error")
]
Dans votre code, chargez-le, puis évaluez-le et compilez les expressions rationnelles dans le résultat:
f = open("messages.py")
messages = eval(f.read()) # caution: you must be sure of what's in that file
f.close()
messages = [(re.compile(r), m) for (r,m) in messages]
et vous vous retrouvez avec une liste de tuples (compiled_regexp, message).
4
répondu Federico A. Ramponi 2008-10-09 12:22:03

Je fais généralement comme Daren l'a suggéré, il suffit de faire de votre fichier de configuration un script Python:

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

Ensuite, vous pouvez l'utiliser comme:

import config

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

C'est ce que Django fait avec son fichier de paramètres, en passant.

3
répondu davidavr 2008-10-09 12:57:56