2010-11-04 15 views
5

Ho un problema. Il mio programma sta usando il file di configurazione per impostare le opzioni, e una di queste opzioni è una tupla. Ecco cosa voglio dire:Lettura array dal file di configurazione in 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/ 

ecc ... posso analizzare questo in tupla con modulo ConfigParser in Python? C'è un modo semplice per farlo?

risposta

8

se è possibile modificare il formato di configurazione in questo modo:

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

poi in python:

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

Non so ConfigParser, ma si può facilmente leggere in un elenco (magari utilizzando .append()) e poi fare myTuple = tuple(myList)

3

È possibile ottenere l'elenco oggetti e utilizzare una lista di comprensione per creare un elenco di tutti le voci il cui nome inizia con un prefisso definito, nel tuo caso cartella

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

Questa soluzione presuppone che le voci nel file siano nell'ordine corretto. –

+0

@Terrel Shumway è disponibile ma è sempre possibile ordinare gli articoli in anticipo. – Rod

+0

l'ordinamento in anticipo non aiuterà: cartella [10]

4

tuo config potrebbero essere:

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

Supponendo di avere config in un file chiamato foo.cfg, è possibile effettuare le seguenti operazioni:

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

print folder 
print type(folder) 

che dovrebbe produrre:

('/ home/scorpil', '/ media/sda5 /', '/ media/sdb5 /')
< tipo 'tupla' >

- EDIT - allora ho cambiato idea su questo, e sarebbe ta la posizione oggi che usare eval in questo contesto è una cattiva idea. Anche con un ambiente limitato, se il file di configurazione è sotto il controllo dell'utente potrebbe essere una pessima idea. Oggi probabilmente raccomanderei di fare qualcosa di interessante con split per evitare l'esecuzione di codice malevolo.

+0

avere un punto, questo mi ha aiutato fuori – cacois

+4

eval() soluzione non è buona, in generale. –

+0

Concordo sul fatto che in generale eval() non è buono. Nel caso in cui controlli l'input e limiti l'ambiente di esecuzione, è una soluzione accettabile. –

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

Crea configurazione: configurazione

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

carico:

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