2010-10-22 15 views
10

Ho un file con il formatoquale sarebbe un modo rapido per leggere un file di proprietà in python?

VarName=Value 
. 
. 

voglio leggere in un hash in modo tale che H("VarName") restituirà il valore.

Quale sarebbe un modo rapido? (Leggere una serie di stringhe, diviso tutti loro dove il segno di uguaglianza è, e poi metterlo in un hash

Sto lavorando con pitone

+5

http://docs.python.org/library/configparser.html? – delnan

risposta

7
d = {} 
with open('filename') as f: 
    for line in f: 
     key, value = line.split('=') 
     d[key] = value 

Edit:?. Come suggerito da Foret, si potrebbe cambiare a

for line in f: 
     tokens = line.split('=') 
     d[tokens[0]] = '='.join(tokens[1:]) 

che gestire il caso in cui è uguale segni sono stati ammessi in valore, ma sarebbe comunque riuscire se il nome potrebbe avere segni uguale, come pure - per questo si avrebbe bisogno di un vero e proprio parser.

+2

Si può semplicemente fare 'per la linea in f'. –

+0

Sì, lo perse inavvertitamente, grazie. – user470379

+2

Cosa succede se il valore contiene '='? =) – foret

9

Forse ConfigParser può aiutarti.

+0

+1 Questa è probabilmente la migliore risposta per i tuoi scopi. – hughdbrown

+10

-1 Tranne che ConfigParser genererà un NoSectionError se non ci sono intestazioni di sezione. – samwyse

2

Il csv module ti consente di fare questo abbastanza facilmente:

import csv 
H = dict([(row[0], row[1]) for row in csv.reader(open('the_file', 'r'), delimiter='=')]) 
+0

Ho risposto ad un'altra domanda con un esempio di codice usando questo tipo di approccio. http://stackoverflow.com/a/13019292/742019 –

20

La risposta oneliner:

H = dict(line.strip().split('=') for line in open('filename.txt')) 

(opzionalmente utilizzare .split() con maxsplit=1 se i valori potrebbero anche contenere il carattere "=")

+0

Mi dispiace, ma questo è un -1. Questo non obbedisce a molte cose valide per la grammatica che è valida per un file di proprietà.Vedere il seguente link per ulteriori dettagli su ciò che manca in questa risposta: https://docs.oracle.com/cd/E23095_01/Platform.93/ATGProgGuide/html/s0204propertiesfileformat01.html. I file delle proprietà, simili a JSON, non hanno una grammatica molto complessa, ma è necessario rispettarli in tutto e per tutto. – searchengine27

2

questa può essere una risposta stupida ma chi lo sa forse può aiutarti :)

cambiare l'estensione del file per .py, e fare il cambiamento necessario in questo modo:

file.py

VarName="Value" # if it's a string 
VarName_2=1 
# and you can also assign a dict a list to a var, how cool is that ? 

e metterlo nel vostro albero pacchetto o in sys.path, e ora si può chiamare in questo modo nello script quando si desidera utilizzarlo:

>>> import file 
>>> file.VarName 
'Value' 

per cui sto scrivendo questa risposta è perché, cosa diavolo è questo file? non vedo mai un file conf come questo, nessuna sezione niente? perché vuoi creare un file di configurazione come questo? sembra un cattivo file di configurazione che dovrebbe assomigliare alle impostazioni di Django, e preferisco usare un file di configurazione simile a django quando posso.

Ora si può mettere il -1 a sinistra :)

+0

È un file di proprietà Java. Abbastanza standard, il che rende vergognoso che ConfigParser lanci un NoSectionError se non ci sono sezioni. Dovrei inviare una richiesta di funzionalità per questo. – samwyse

+0

Mi piace che tu stia pensando fuori dagli schemi, ma questo si romperà su una riga come "VarName: value", che si rompe entrambi sul carattere ':', e sul fatto che il tuo 'valore' non ha virgolette intorno esso. – searchengine27

+0

Inoltre, i file @samwyse: .cfg, pur non avendo la centralizzazione di una grammatica formale come file .properties, vengono comunemente interpretati in modo diverso rispetto a .properties. 'ConfigParser' è una libreria per capire i file .cfg, quindi se scrivi un bug contro quella libreria per non leggere .properties, è probabile che lo respingano e lo rifiutino - lo farei comunque. I file .properties non sono responsabilità di un parser .cfg. I file .cfg richiedono l'esistenza di una sezione nella maggior parte dei gestori .cfg, motivo per cui viene generata quell'eccezione. – searchengine27

8

Prendendo @ risposta di Steven non tiene conto commenti e ritorni a capo nelle proprietà del file, questo si fa:

H = dict(line.strip().split('=') for line in open('file.properties') if not line.startswith('#') and not line.startswith('\n')) 
+0

Mi dispiace ma questo ha lo stesso problema di @Steven. Se questo obbedisse alla grammatica, rimuoverei il downvote, o se la risposta avesse almeno riconosciuto che non si stava analizzando un file delle proprietà. – searchengine27

0

Se avete bisogno per leggere tutti i valori da una sezione nel file delle proprietà in modo semplice:

Config.proprietà file di layout:

[SECTION_NAME]

chiave1 = valore1

chiave2 = valore2 codice

È:

import configparser 

    config = configparser.RawConfigParser() 
    config.read('path_to_config.properties file') 

    details_dict = dict(config.items('SECTION_NAME')) 

questo vi darà un dizionario in cui le chiavi sono le stesse nel file di configurazione e i loro valori corrispondenti.

details_dict è:

{'key1':'value1', 'key2':'value2'} 
1

Per python2 c'è un jproperties https://pypi.python.org/pypi/jproperties/1.0.1

Per python2/3 c'è javaproperties http://javaproperties.readthedocs.io/en/v0.1.0/

semplice come:

import os, javaproperties 
with open(file, 'rb') as f: 
    properties_dict = javaproperties.load(f) 
+0

Questa è onestamente l'unica soluzione completa qui che effettivamente il 100 percento risolve il problema dell'OP. L'unico problema potrebbe essere l'uso di librerie di terze parti che potrebbero essere limitate dalla sua organizzazione, come spesso accade nel mondo aziendale. Una soluzione che ho per lo stesso problema richiede l'uso di una libreria separata, quindi non ho una soluzione migliore, necessariamente - solo diversa. – searchengine27

0

OK nessuno altro nelle risposte lo ha menzionato, quindi credo che lo farò. Se stai scrivendo Python e hai il controllo dell'interprete, forse puoi forzare l'uso dell'interprete Jython.

Jython è un interprete Python implementato interamente in Java. Avete tutte le librerie standard Python a portata di mano, con l'ulteriore vantaggio di tutte le vostre librerie Java SE disponibili.

Non ho effettivamente eseguito nessuna delle seguenti operazioni (pensate più come psudeo-code senza gestione delle eccezioni), ma potete mescolare e abbinare le librerie Python e Java e il vostro codice potrebbe apparire come:

from java.util import Properties 
from java.io import File, FileInputStream 
import os 
javasPropertyObject = Properties() 
pathToPropFile = os.path.join('path', 'to', 'property', 'file.properties') 
if os.path.isfile(pathToPropFile): 
    #this is java.io.File, not Python's file descriptor 
    propFile = File(pathToPropFile) 
    javasFileInputStreamObject = FileInputStream(propFile) 
    javasPropertyObject.load(javasFileInputStreamObject) 

    #now we can pull out Java properties as defined by the .property file grammar 
    myProp = javasPropertyObject.getProperty('myPropName') 

in cui un file come questo sarà valido, che non sarebbe nelle semplici split on '=' soluzioni:

myPropName1:value 
myPropName2=value 
myPropName3=\ 
value 
#this is a = comment 
myPropName4:my \ 
value 
myPropNameWithUnicode=\u0009 

Il rovescio della medaglia, è che si perde la capacità di essere portabile tra i diversi interpreti Python e ora sei bloccato in Jython . Sarai rinchiuso in una biblioteca se tenterai anche tu questo approccio. Il motivo per cui mi piace Jython è la tua maggiore flessibilità con l'avere tutte le librerie Java SE disponibili.

Problemi correlati