2010-11-04 15 views
5

J'ai un problème. Mon programme utilise le fichier de configuration pour définir les options, et l'une de ces options est un tuple. Voici ce que je veux dire:Lecture d'un tableau à partir du fichier de configuration en python

[common] 
logfile=log.txt 
db_host=localhost 
db_user=root 
db_pass=password 
folder[1]=/home/scorpil 
folder[2]=/media/sda5/ 
folder[3]=/media/sdb5/ 

etc ... Puis-je analyser cela en tuple avec module ConfigParser en Python? Y at-il un moyen facile de le faire?

Répondre

8

si vous pouvez modifier le format config comme ceci:

folder = /home/scorpil 
     /media/sda5/ 
     /media/sdb5/ 

puis en python:

config.get("common", "folder").split("\n") 
1

Je ne sais pas ConfigParser, mais vous pouvez facilement lire dans une liste (en utilisant peut-être .append()) puis faire myTuple = tuple(myList)

3

Vous pouvez obtenir la liste des articles et utiliser une compréhension de liste pour créer une liste de tous les éléments dont le nom commence par un préfixe défini, dans votre cas dossier

folders = tuple([ item[1] for item in configparser.items() if item[0].startswith("folder")]) 
+0

Cette solution suppose que les entrées dans le fichier sont dans le bon ordre. –

+0

@Terrel Shumway est fait mais vous pouvez toujours trier les éléments à l'avance. – Rod

+0

tri préalable ne va pas aider: dossier [10]

4

votre config pourrait être:

[common] 
logfile=log.txt 
db_host=localhost 
db_user=root 
db_pass=password 
folder = ("/home/scorpil", "/media/sda5/", "/media/sdb5/") 

En supposant que vous avez config dans un fichier nommé foo.cfg, vous pouvez effectuer les opérations suivantes:

import ConfigParser 
cp = ConfigParser.ConfigParser() 
cp.read("foo.cfg") 
folder = eval(cp.get("common", "folder"), {}, {}) 

print folder 
print type(folder) 

qui devrait produire:

('/ home/scorpil', «/media/sda5/», '/ media/sdb5 /')
< type 'tuple' >

- EDIT - je l'ai depuis changé d'avis à ce sujet, et serait ta ke la position aujourd'hui que l'utilisation d'eval dans ce contexte est une mauvaise idée. Même avec un environnement restreint, si le fichier de configuration est sous le contrôle de l'utilisateur, cela peut être une très mauvaise idée. Aujourd'hui, je recommanderais probablement de faire quelque chose d'intéressant avec split pour éviter l'exécution de code malveillant.

+0

avoir un point, cela m'a aidé – cacois

+4

eval() solution n'est pas bon, d'une manière générale. –

+0

Je suis d'accord qu'en général eval() n'est pas bon. Dans le cas où vous contrôlez l'entrée, et restreignez l'environnement d'exécution, c'est une solution acceptable. –

1
#!/usr/bin/env python 
sample = """ 
[common] 
logfile=log.txt 
db_host=localhost 
db_user=root 
db_pass=password 
folder[1]=/home/scorpil 
folder[2]=/media/sda5/ 
folder[3]=/media/sdb5/ 
""" 
from cStringIO import StringIO 
import ConfigParser 
import re 
FOLDER_MATCH = re.compile(r"folder\[(\d+)\]$").match 

def read_list(items,pmatch=FOLDER_MATCH): 
    if not hasattr(pmatch,"__call__"): 
     pmatch = re.compile(pmatch).match 
    folder_list = [] 
    for k,v in items: 
     m = pmatch(k) 
     if m: 
      folder_list.append((int(m.group(1)),v)) 
    return tuple(kv[1] for kv in sorted(folder_list)) 


if __name__ == '__main__': 
    cp = ConfigParser.SafeConfigParser() 
    cp.readfp(StringIO(sample),"sample") 

    print read_list(cp.items("common")) 
1

configuration Créer:

folders = ['/home/scorpil', '/media/sda5/', '/media/sdb5/'] 
config.set('common', 'folders', json.dumps(folders)) 

Configuration de la charge:

tuple(json.loads(config.get('common', 'folders')))