2009-10-23 14 views
54

Ho provato a utilizzare il modulo ConfigParser di Python per salvare le impostazioni. Per la mia app è importante che conservi il caso di ciascun nome nelle mie sezioni. I documenti menzionano che passare str() a ConfigParser.optionxform() porterebbe a termine questo, ma non funziona per me. I nomi sono tutti in minuscolo. Mi sto perdendo qualcosa?Preserva il caso in ConfigParser?

<~/.myrc contents> 
[rules] 
Monkey = foo 
Ferret = baz 

Python pseudocodice di quello che ottengo:

import ConfigParser,os 

def get_config(): 
    config = ConfigParser.ConfigParser() 
    config.optionxform(str()) 
    try: 
     config.read(os.path.expanduser('~/.myrc')) 
     return config 
    except Exception, e: 
     log.error(e) 

c = get_config() 
print c.options('rules') 
[('monkey', 'foo'), ('ferret', 'baz')] 

risposta

73

La documentazione è confusa. Ciò che intendono è:

import ConfigParser, os 
def get_config(): 
    config = ConfigParser.ConfigParser() 
    config.optionxform=str 
    try: 
     config.read(os.path.expanduser('~/.myrc')) 
     return config 
    except Exception, e: 
     log.error(e) 

c = get_config() 
print c.options('rules') 

I.e. override di optionxform, invece di chiamarlo; la sovrascrittura può essere eseguita in una sottoclasse o nell'istanza. Quando si esegue l'override, impostarlo su una funzione (anziché sul risultato di chiamare una funzione).

Ho ora segnalato this as a bug e da allora è stato risolto.

+0

Grazie. Funziona, e sono d'accordo sul fatto che i documenti siano confusi. – pojo

+4

+1 per aver segnalato il bug – Tshepang

2

So che questa domanda ha una risposta, ma ho pensato che alcune persone potrebbero trovare utile questa soluzione. Questa è una classe che può facilmente sostituire la classe esistente di ConfigParser.

A cura di incorporare il suggerimento di @ OozeMeister:

class CaseConfigParser(ConfigParser): 
    def optionxform(self, optionstr): 
     return optionstr 

uso è lo stesso di ConfigParser normale.

parser = CaseConfigParser() 
parser.read(something) 

Questo è così si evita di dover impostare optionxform ogni volta che fate un nuovo ConfigParser, che è una specie di noioso.

+0

Dato che 'optionxform' è solo un metodo sul' RawConfigParser', se vuoi arrivare alla creazione della tua sottoclasse, dovresti semplicemente sovrascrivere il metodo nella sottoclasse piuttosto che ridefinire per istanza: 'class CaseConfigParser (ConfigParser): def optionxform (self, optionstr): return optionstr' – OozeMeister

+0

@OozeMeister ottima idea! – icedtrees

20

Per me ha funzionato per impostare optionxform subito dopo aver creato l'oggetto

config = ConfigParser.RawConfigParser() 
config.optionxform = str 
+1

Funziona alla grande! (notare che in python 3 è il nome di classe "configparser" (senza lettere maiuscole) –

+0

@NoamManos: si fa riferimento al nome del modulo (il nome della classe è ancora [ConfigParser] (https://docs.python.org/3/ library/configparser.html # configparser.ConfigParser)). –

+0

Nota che funziona anche con 'ConfigParser.ConfigParser()' –

0

Caveat:

Se si utilizzano le impostazioni predefinite con ConfigParser, vale a dire:

config = ConfigParser.SafeConfigParser({'FOO_BAZ': 'bar'}) 

e quindi provare a fare il parser case-sensitive usando questo:

config.optionxform = str 

tutte le opzioni da file di configurazione manterranno il loro caso, ma FOO_BAZ verrà convertito in lettere minuscole.

Per avere valori predefiniti mantenere anche il loro caso, utilizzano sottoclassi come in @icedtrees rispondere:

class CaseConfigParser(ConfigParser.SafeConfigParser): 
    def optionxform(self, optionstr): 
     return optionstr 

config = CaseConfigParser({'FOO_BAZ': 'bar'}) 

Ora FOO_BAZ manterrà E 'caso e non avrà InterpolationMissingOptionError.