Seite 1 von 2
ConfigParser: Wie setzt man Default-Werte?
Verfasst: Montag 19. Januar 2009, 16:30
von api
Hallo zusammen,
ich möchte eigentlich nur mittels des ConfigParser's eine INI-Datei einlesen - allerdings muss gewährleistet sein, dass fehlende Keys bzw. Sections per Default hinterlegt sind.
Mein Code sieht also zB so aus:
INI-Datei
[CONF]
LOG_LEVEL=1
Python-Programm:
Code: Alles auswählen
import ConfigParser
config = ConfigParser.ConfigParser()
config.read(['test.conf'])
print config.get('CONF', 'LOG_LEVEL')
print config.get('CONF', 'ACT_VALUE')
Der Key 'ACT_VALUE' befindet sich nun gar nicht im INI-File. Gibt es eine Möglichkeit im Python-Programm Defaults für so etwas zu hinterlegen?
CU,
API
Verfasst: Montag 19. Januar 2009, 16:35
von querdenker
Vorschlag: Wert aus dem Config-File abfragen -> wenn der nicht da ist, sollte es eine Exception geben. Auf die kannst du dann mit einem config.set(...) reagieren.
Verfasst: Montag 19. Januar 2009, 16:44
von api
Hallo querdenker,
dass mit ner Exception abzufangen wäre zwar ne Möglichkeit, aber da ich zig Keys/Values in dieser INI-Datei stehen habe (Beispiel ist nur ein Auszug), müsste ich das dann für jeden Wert seperat machen.
Gibt es da noch andere Möglichkeiten?
CU,
API
Verfasst: Montag 19. Januar 2009, 16:56
von DasIch
Code: Alles auswählen
import ConfigParser as cfgp
class Config(cfgp.ConfigParser):
def get(self, section, option, default=None, **kwargs):
if default is None:
return cfgp.ConfigParser.get(self, section, option, **kwargs)
try:
return cfgp.ConfigParser.get(self, section, option, **kwargs)
except cfgp.NoOptionError:
return default
Du könntest auch ein dict nehmen und dort den Standard Wert nachschlagen.
Verfasst: Montag 19. Januar 2009, 16:59
von cofi
Wenn ich das richtig sehe unterstützt
ConfigObj von sich aus Defaults. Und hat auch ein paar andere Vorteile gegenüber configparser.
Verfasst: Montag 19. Januar 2009, 17:01
von helduel
Moin,
nicht so kompliziert, bitte. In der Doku zum ConfigParser steht, wie man default-Werte festlegt:
Code: Alles auswählen
import ConfigParser
# New instance with 'bar' and 'baz' defaulting to 'Life' and 'hard' each
config = ConfigParser.SafeConfigParser({'bar': 'Life', 'baz': 'hard'})
config.read('example.cfg')
print config.get('Section1', 'foo') # -> "Python is fun!"
config.remove_option('Section1', 'bar')
config.remove_option('Section1', 'baz')
print config.get('Section1', 'foo') # -> "Life is hard!"
Gruß,
Manuel
Verfasst: Montag 19. Januar 2009, 17:30
von api
Hallo Manuel,
wenn ich bei meinem obigen Beispiel bleibe, bekomme ich mit folgendem Python-Code diese Fehlermeldung:
Code: Alles auswählen
import ConfigParser
config = ConfigParser.SafeConfigParser({'ACT_VALUE':'100'})
config.read(['test.conf'])
print config.get('CONF', 'LOG_LEVEL')
print config.get('CONF', 'ACT_VALUE')
1
Traceback (most recent call last):
File "tt.py", line 8, in ?
print config.get('CONF', 'ACT_VALUE')
File "/usr/sfw/lib/python2.3/ConfigParser.py", line 513, in get
raise NoOptionError(option, section)
ConfigParser.NoOptionError: No option 'act_value' in section: 'CONF'
Was ist da noch falsch?
CU,
API
Verfasst: Montag 19. Januar 2009, 17:41
von Hyperion
Guck doch mal, was Dir
ausgibt!
Ich wette da findest Du das ACT_VALUE!
So wie ich das verstanden habe, kann man nur default Werte übergeben, die in keiner Section stehen, also global gültig sind! Das ist bei Dir ja nicht der Fall. (Was helduel mal nicht gesagt hat

)
Außer man kann das dict so erweitern, dass man die Section mit angeben kann, etwa:
Code: Alles auswählen
config = ConfigParser.SafeConfigParser({'CONF':{'ACT_VALUE':'100'}})
Verfasst: Montag 19. Januar 2009, 17:52
von api
Wenn ich das so erweitere, bekomme ich folgende Ausgabe:
Code: Alles auswählen
import ConfigParser
config = ConfigParser.SafeConfigParser({'CONF':{'ACT_VALUE':'100'}})
config.read(['test.conf'])
print config.get('CONF', 'LOG_LEVEL')
print config.defaults()
print config.get('CONF', 'ACT_VALUE')
{'CONF': {'ACT_VALUE': '100'}}
Traceback (most recent call last):
File "tt.py", line 9, in ?
print config.get('CONF', 'ACT_VALUE')
File "/usr/sfw/lib/python2.3/ConfigParser.py", line 513, in get
raise NoOptionError(option, section)
ConfigParser.NoOptionError: No option 'act_value' in section: 'CONF'
Die Frage ist jetzt nur, was ich mit dieser Info anfangen kann...
CU,
API
Verfasst: Montag 19. Januar 2009, 18:05
von Hyperion
api hat geschrieben:
Die Frage ist jetzt nur, was ich mit dieser Info anfangen kann...
Nicht viel, weil Du meine Mutmaßung einfach so übernommen hast! Probiere es doch einmal ohne das verschachtelete dict!
Code: Alles auswählen
In [5]: config = ConfigParser.SafeConfigParser({'ACT_VALUE':'100'})
In [6]: print config
<ConfigParser.SafeConfigParser instance at 0x912810c>
In [7]: print config.defaults()
{'act_value': '100'}
In [8]: print config.sections()
[]
Schau Dir das einfach an!
Verfasst: Montag 19. Januar 2009, 18:40
von api
Eine wirklich gute Idee!!!
Ich habe das jetzt mal folgendermaßen gelöst:
Code: Alles auswählen
import ConfigParser
config = ConfigParser.SafeConfigParser({'ACT_VALUE':'100', 'LOG_LEVEL':'3'})
config.read(['test.conf'])
def SetValue (sv_section, sv_key):
try:
value = config.get(sv_section, sv_key)
except:
value = config.defaults()[sv_key]
return value
ActValue = SetValue ('CONF', 'ACT_VALUE')
LogLevel = SetValue ('CONF', 'LOG_LEVEL')
print "ActValue: %s" % ActValue
print "LogLevel: %s" % LogLevel
...und das ergibt...
Das ist genau das, was ich mir vorgestellt habe... Danke für die Hilfe!!
CU,
API
Verfasst: Montag 19. Januar 2009, 18:52
von DasIch
Das ist keine Lösung dass ist ein Verbrechen.
Verfasst: Montag 19. Januar 2009, 19:07
von cofi
Warum benutzt du überhaupt den Abschnitt `CONF' in einer Konfigurationsdatei? Reicht es nicht wenn die schlicht und einfach Top-Level sind?
Verfasst: Dienstag 20. Januar 2009, 08:50
von BlackJack
@cofi: Der ConfigParser will zwingend mindestens einen benannten Abschnitt in der Konfigurationsdatei haben.
Verfasst: Dienstag 20. Januar 2009, 10:22
von lunar
Dann wäre ConfigObj vielleicht doch eine Option, da es auch Konfigurationsdateien ohne Abschnitte parsen kann.
Verfasst: Dienstag 20. Januar 2009, 10:37
von helduel
@api: Wäre interessant, wie deine Config aussieht. Bei mir hier funzt alles, wie erwartet:
foo.conf
test.pyCode: Alles auswählen
from ConfigParser import SafeConfigParser
config = SafeConfigParser({"foo": "123", "bar": "456", "baz": "789"})
config.read("foo.conf")
print "main", config.get("main", "foo")
print "main", config.get("main", "bar")
print "main", config.get("main", "baz")
print "blubber", config.get("blubber", "bar")
print "blubber", config.get("blubber", "baz")
Ausgabe
Gruß,
Manuel
Verfasst: Dienstag 20. Januar 2009, 11:31
von api
@helduel: Ich habe das mal ausprobiert und mich wirklich gefragt, warum ich das wie oben beschrieben realisiert habe... Dann hab ich das nach deiner Lösung umgesetzt - und du hast recht: Das ist ja viel einfacher und übersichtlicher. Das Problem bei mir war die Config-Datei. Sie hatte folgendes Aussehen:
Mit den großen Buchstaben funzt das aber nicht und wirft eben eine Fehlermeldung...
Wenn ich die Config-Datei so umsetze:
und alle anderen Keys ebenfalls in Kleinbuchstaben, dann ist alles wie erwartet...
Na, wunderbar...
CU,
API
Verfasst: Dienstag 20. Januar 2009, 11:37
von api
@DasIch: Mich würde mal interessieren, warum du diese "Lösung" als Verbrechen! bezeichnest. Könntest du diese Aussage mal konkretisieren, denn mit mit diesem Statement alleine kann ich nun aber auch gar nichts anfangen.
Ich bin ja gerne bereit, andere Lösungsvorschläge zu akzeptieren, aber etwas detaillierter würde schon etwas mehr dazu beitragen...
Verfasst: Dienstag 20. Januar 2009, 13:08
von Leonidas
Ich nehme mal an dass du die Funktionen konsequent falsch beannt hast und weil du alle Exceptions schluckst, was schlichtweg schädlich ist, da du so auch Exceptions fängst die du eigentlich gar nicht fangen wolltest.
Verfasst: Dienstag 20. Januar 2009, 14:12
von api
@Leonidas: Mit den Exceptions gebe ich dir recht. Das alles mit einer einzigen abzufackeln ist nicht wirklich sauber. Aber ich habe das als Beispiel angesehen und in der realen Lösung hätten da nicht nur ein paar mehr sondern auch eindeutigere Exceptions gestanden.
Es ging mir in diesem Augenblick mehr um das Handling mit dem ConfigParser.
Aber was mich dann doch interessieren würde, was du mit konsequenter Falschbenennung von Funktionen meinst? Was mache ich da falsch? Nenn mir doch bitte mal ein Beispiel und wenn möglich dann gleich auch wie es richtig sein müsste...
CU,
API