Conserva maiuscole e minuscole in ConfigParser?


92

Ho provato a utilizzare il modulo ConfigParser di Python per salvare le impostazioni. Per la mia app è importante che conservi il caso di ogni nome nelle mie sezioni. La documentazione menziona che il passaggio di str () a ConfigParser.optionxform () lo farebbe, ma per me non funziona. I nomi sono tutti in minuscolo. Mi sto perdendo qualcosa?

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

Pseudocodice Python di ciò 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')]

Risposte:


116

La documentazione è confusa. Quello che vogliono dire è questo:

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')

Vale a dire sovrascrivere optionxform, invece di chiamarlo; l'override può essere eseguito in una sottoclasse o nell'istanza. Quando si esegue l'override, impostarlo su una funzione (piuttosto che sul risultato della chiamata di una funzione).

Ora l'ho segnalato come un bug e da allora è stato risolto.


Grazie. Funziona e sono d'accordo che i documenti creano confusione.
pojo

39

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

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

2
Funziona alla grande! (nota che in python 3 è il nome della classe "configparser" (non maiuscolo)
Noam Manos

1
@NoamManos: ti riferisci al nome del modulo (il nome della classe è ancora ConfigParser ).
Jonas Byström

2
Nota che funziona anche conConfigParser.ConfigParser()
Jean-Francois T.

Infatti. Funziona. È utile ricordare che questo parametro non è associato essenzialmente a RawConfigParser (), poiché è supportato anche dalla classe ConfigParser (). Grazie uomo.
ivanleoncz

7

Aggiungi al tuo codice:

config.optionxform = lambda option: option  # preserve case for letters

1
Questo sembra funzionare per me almeno in Python 2.7 ed è molto più pulito della risposta accettata. Grazie foo!
hrbdg

2
questo è lo stesso della risposta con il punteggio più alto - vedi la riga config.optionxform=str:) solo invece della tua lamdba @Martin v. Löwis usa la strfunzione incorporata
xuthus

@xuthus - In effetti, puoi usare 11 righe di codice invece di 1 riga. Come desidera.
FooBar167

4

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 ConfigParser esistente.

Modificato per incorporare il suggerimento di @ OozeMeister:

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

L'utilizzo è lo stesso del normale ConfigParser.

parser = CaseConfigParser()
parser.read(something)

In questo modo eviti di dover impostare optionxform ogni volta che ne crei uno nuovo ConfigParser, il che è un po 'noioso.


Da optionxform è solo un metodo sulla RawConfigParser, se hai intenzione di creare la tua sottoclasse, dovresti invece sovrascrivere il metodo sulla sottoclasse piuttosto che ridefinirlo per istanziazione:class CaseConfigParser(ConfigParser): def optionxform(self, optionstr): return optionstr
OozeMeister

@OozeMeister ottima idea!
icedtrees

2

Avvertimento:

Se utilizzi i valori predefiniti con ConfigParser, ovvero:

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

e quindi provare a rendere il parser sensibile al maiuscolo / minuscolo usando questo:

config.optionxform = str

tutte le opzioni dai file di configurazione manterranno il loro caso, ma FOO_BAZ verranno convertite in minuscolo.

Per fare in modo che anche i valori predefiniti mantengano il loro caso, usa la sottoclasse come nella risposta di @icedtrees:

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

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

Adesso FOO_BAZ manterrà il suo caso e non avrai InterpolationMissingOptionError .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.