OVH Cloud OVH Cloud

lire le fichier de configuration

5 réponses
Avatar
R12y
Bonjour,

Y a t il une manière particulière, ou un algorithme particulier pour lire
un fichier de configuration?
Je parle des fichiers de configuration qui contiennent des lignes du genre:

param1 = val1
param2 = val2
..
paramX = valX

D'après ma vision très débutante de la chose, on peut dans un premier
temps lire le fichier de conf en entier et stocker le paramétrage dans un
dictionnaire (Python, par exemple, a ce type) ou t'ablea d'association
(Perl). Mais est ce qu'il y a d'autres façon de faire? J'ai bien essayé de
voir comment font les programmes open source qui existent mais je n'ai pas
le niveau necessaire pour comprendre comment il font.

En fait, je sais me débrouiller pour parser ce genre de fichier (même en
tenant compte des commentaires. Le tout est en fait de savoir si il y a
déjà des libs/modules/packages spécialement fait pour, ou bien à chaque
projet, on refait la roue...

Le programme que je compte écrire le sera en Python.

Merci.

PS: Attention au follow-up...

--
Telephone portable "intelligent" (SmartPhone) GSM, GPRS,...
Il est sous Linux, ne coute pas trop cher,...
http://www.it2l.com/product_info.php?cPath=91&products_id=456

5 réponses

Avatar
bruno at modulix
Andréï wrote:

<meta>xpost et fu2 fclpy</meta>

R12Y a écrit

Y a t il une manière particulière, ou un algorithme particulier pour lire
un fichier de configuration?
Je parle des fichiers de configuration qui contiennent des lignes du
genre:

param1 = val1
param2 = val2
..
paramX = valX

(snip)




import os
try:
fichier=open('nom_du_fichier.conf','r')
listeslignes= fichier.readlines()
finally:
fichier.close()
dictconf = {}
def assignation(clee, valeur):
dictconf[clee]=valeur
[assignation(i.split("=")[0],i.split("=")[1]) for i in listeslignes if
len(i.split("="))==2]


Pas très efficace. D'une part, tu montes tout le fichier en mémoire, ce
qui n'est pas utile, d'autre part tu appelles 3 fois str.split alors
qu'il suffit d'une, et enfin construit une liste pour rien.

Accessoirement, tu restreins l'utilisation à un fichier, alors que
n'importe quelle autre source pourrait être valide...

class ConfigError(Exception):
# TODO : find a more appropriate superclass
pass

def parse_ini(fin):
section = conf = {}
for numline, line in enumerate(fin):
line = line.strip()

# handle comments
if line.startswith('#'):
continue

# handle sub sections (ie: [mysubsection])
if line.startswith('['):
if not line.endswith(']'):
raise ConfigError("invalid config : line %d : '%s'"
% (numline, line))
section_name = line.strip('[]').strip()
if not section_name:
raise ConfigError("invalid config : line %d : '%s'"
% (numline, line))

section = conf[section_name] = {}
continue

# sanity check
if not '=' in line:
raise ConfigError("invalid config : line %d : '%s'"
% (numline, line))
k, v = (part.strip() for part in line.split('=', 1))

if not k or not v:
raise ConfigError("invalid config : line %d : '%s'"
% (numline, line))
# ok, assign to current section
section[k] = v

return conf

def parse_ini_file(filename):
fin = open(filename, 'r')
try:
return parse_ini(fin)
finally:
fin.close()

Voili voila. C'est un peu plus long, mais bon, hein... !-)

Maintenant, si tu aimes les acrobaties, il y a aussi ça:

conf = dict([tuple([part.strip() for part in line.split('=', 1)])
for line in open(filename)
if '=' in line and not line.startswith('#')])

Mais c'est moins robuste, et pas forcément plus rapide... (et puis ça ne
gère pas les sous-sections)


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Andréï
Salut,
Pas très efficace. D'une part, tu montes tout le fichier en mémoire, ce
qui n'est pas utile, d'autre part tu appelles 3 fois str.split alors
qu'il suffit d'une, et enfin construit une liste pour rien.
Accessoirement, tu restreins l'utilisation à un fichier, alors que
n'importe quelle autre source pourrait être valide...



Merci pour tes remarques constructives, je n'ai visiblement pas ton
expérience.

Voili voila. C'est un peu plus long, mais bon, hein... !-)

Maintenant, si tu aimes les acrobaties, il y a aussi ça:

conf = dict([tuple([part.strip() for part in line.split('=', 1)])
for line in open(filename)
if '=' in line and not line.startswith('#')])

j'ai commencé avec "dive in python" et ils en font beaucoups des

acrobaties comme ça.

Mais c'est moins robuste, et pas forcément plus rapide... (et puis ça ne
gère pas les sous-sections)


Je n'avais pas pensé aux commentaires aux sous-sections.

ps: mon post n'est pas apparu sur la liste de mon newsreader
("mesmews").

byebye

Avatar
R12y
On Tue, 13 Dec 2005 13:00:41 +0100, Andréï wrote:

ps: mon post n'est pas apparu sur la liste de mon newsreader
("mesmews").


J'avais placé un "suivi sur un autre groupe" sur le post initial.
D'ou la mention "Attention au Follow up" à la fin du message initial.
Jette un oeil aux en-têtes du message initial.

--
Telephone portable "intelligent" (SmartPhone) GSM, GPRS,...
Il est sous Linux, ne coute pas trop cher,...
http://www.it2l.com/product_info.php?cPath‘&products_idE6

Avatar
bruno at modulix
R12y wrote:
On Tue, 13 Dec 2005 13:00:41 +0100, Andréï wrote:


ps: mon post n'est pas apparu sur la liste de mon newsreader
("mesmews").



J'avais placé un "suivi sur un autre groupe" sur le post initial.
D'ou la mention "Attention au Follow up" à la fin du message initial.
Jette un oeil aux en-têtes du message initial.

Et moi redirigé celui-ci vers fclpy, puisque c'est spécifique Python...


--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Christophe Delord
Bonjour,

On Tue, 13 Dec 2005 11:02:16 +0100, bruno at modulix wrote:

Andréï wrote:

Maintenant, si tu aimes les acrobaties, il y a aussi ça:

conf = dict([tuple([part.strip() for part in line.split('=', 1)])
for line in open(filename)
if '=' in line and not line.startswith('#')])



Dans le genre one-liner, on peut aussi écrire (en python 2.4) :

conf = dict(re.findall(r"^s*(w+)s*=s*(.*?)s*$",
file(fichier).read(), re.MULTILINE))

En python 2.3 il faut compiler l'expression régulière à part pour
pouvoir spécifier l'option MULTILINE :

cfg_re = re.compile(r"^s*(w+)s*=s*(.*?)s*$", re.MULTILINE)
conf = dict(cfg_re.findall(file(fichier).read()))

ou

conf = dict(re.compile(r"^s*(w+)s*=s*(.*?)s*$",re.MULTILINE).finda ll(file(fichier).read()))