2009-10-23 12 views
54

Ich habe versucht, Pythons ConfigParser Modul zu verwenden, um Einstellungen zu speichern. Für meine App ist es wichtig, dass ich den Fall jedes Namens in meinen Abschnitten aufbewahre. Die Dokumentation erwähnt, dass die Übergabe von str() an ConfigParser.optionxform() dies erreichen würde, aber es funktioniert nicht für mich. Die Namen sind alle Kleinbuchstaben. Fehle ich etwas?Fall in ConfigParser beibehalten?

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

Python Pseudo-Code von dem, was ich bekommen:

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

Antwort

73

Die Dokumentation ist verwirrend. Was sie bedeuten, ist dies:

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 optionxform, anstatt es aufzurufen; Überschreiben kann in einer Unterklasse oder in der Instanz erfolgen. Legen Sie beim Überschreiben eine Funktion fest (und nicht das Ergebnis des Aufrufs einer Funktion).

Ich habe jetzt this as a bug gemeldet, und es wurde seit behoben.

+0

Vielen Dank. Es funktioniert, und ich stimme zu, dass die Dokumente verwirrend sind. – pojo

+4

+1 für das Melden des Fehlers – Tshepang

2

Ich weiß, dass diese Frage beantwortet wird, aber ich dachte, dass einige Leute diese Lösung nützlich finden könnten. Dies ist eine Klasse, die die vorhandene ConfigParser-Klasse problemlos ersetzen kann.

Edited @ OozeMeister Vorschlag zu übernehmen:

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

Verwendung der gleiche wie normale ConfigParser ist.

parser = CaseConfigParser() 
parser.read(something) 

Dies ist so, jedes Mal, wenn eine neue ConfigParser machen setzen optionxform Sie vermeiden, dass, was irgendwie langweilig ist.

+0

Da 'optionxform' nur eine Methode für' RawConfigParser' ist, sollten Sie die Methode für die Unterklasse überschreiben und nicht neu definieren, wenn Sie selbst eine eigene Unterklasse erstellen möchten es pro Instantiierung: 'Klasse CaseConfigParser (ConfigParser): def Optionxform (self, optionstr): Rückgabe optionstr' – OozeMeister

+0

@OozeMeister tolle Idee! – icedtrees

20

Für mich war sofort einzustellen optionxform nach Erstellen des Objekts

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

Funktioniert gut! (Beachten Sie, dass es in Python 3 der Klassenname "configparser" ist (kein Großbuchstabe) –

+0

@NoamManos: Sie beziehen sich auf den Modulnamen (der Klassenname ist immer noch [ConfigParser] (https://docs.python.org/3/ library/configparser.html # configparser.ConfigParser)). –

+0

Beachten Sie, dass es auch mit 'ConfigParser.ConfigParser()' funktioniert –

0

Caveat:

Wenn Sie Standardwerte mit ConfigParser verwenden, das heißt:

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

und dann versuchen, das zu machen, Parser Groß-und Kleinschreibung mit diesem:

config.optionxform = str 

Alle Ihre Optionen aus Konfigurationsdatei (en) behalten ihren Fall, aber FOO_BAZ wird in Kleinbuchstaben konvertiert.

Um Ausfälle halten auch ihren Fall, verwenden Subklassifizieren wie in @icedtrees beantworten:

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

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

Jetzt FOO_BAZ es ist Fall zu halten, und Sie werden InterpolationMissingOptionError nicht haben.