Seite 1 von 1
very simple CFG-Parser...
Verfasst: Mittwoch 18. August 2004, 18:05
von jens
Hab einen wirklich einfachen CFG-Parser geschrieben...
Code: Alles auswählen
# SimpleCfg.py
from os import path
from os import environ
class cfg:
def __init__(self,Datei):
if not path.isfile(Datei):
raise "Datei "+Datei+" existiert nicht! Aktueller Pfad:",path.abspath(".")
try:
CfgDatei=open(Datei,"r")
except:
raise "Öffnen von:"+Datei+" fehlgeschlagen!"
self.CfgDaten={}
while 1:
Zeile = CfgDatei.readline()
if not Zeile:
break
if not Zeile[0]=="#" and ":" in Zeile:
Daten=Zeile.split(":")
self.CfgDaten[Daten[0].strip()]=Daten[1].strip()
CfgDatei.close()
def getItem(self,Item,ErrorHandling=False):
if Item in self.CfgDaten:
return self.CfgDaten[Item]
elif ErrorHandling:
return False
else:
raise "Item: [",Item,"] nicht in Cfg-Datei gefunden!"
Eine Beispiel CFG-Datei:
Code: Alles auswählen
# Beispiel.cfg
# Kommentar
Name: Wert
Wert: 1
Python ist wie?: Python ist super!
Zum Ausführen:
Code: Alles auswählen
# test.py
import SimpleCfg
MyCfg=SimpleCfg.cfg("Beispiel.cfg")
print MyCfg.getItem("Name")
print MyCfg.getItem("Wert")
print MyCfg.getItem("Python ist wie?")
Und das kommt raus:
Zu beachten ist, das alle Ergebnisse erstmal ein String sind. Also auch Wert=1 ist eigentlich Wert="1"
Das "ErrorHandling" bei der Funktion getItem produziert Standartmäßig einen fehler, wenn ein Wert nicht gefunden wird, aber so kann man es verhindern:
print MyCfg.getItem("NichtVorhanden", True)
Dann erhält man nur ein False zurück und kann es irgendwie anders handeln...
Verfasst: Mittwoch 18. August 2004, 18:53
von Dookie
Hi jens,
hast Dir schonmal den Configparser von Python angeschaut, oder das ->
http://python.sandtner.org/viewtopic.php?t=1785 ?
Gruß
Dookie
Verfasst: Mittwoch 18. August 2004, 19:02
von jens
Den Configparser von Python kenne ich noch nicht... Ist aber wahrscheinlich Overkill, oder???
Der andere Thread ist aber super! Danke

Verfasst: Dienstag 8. März 2005, 21:57
von jens
Ich hab mir nun doch den eingebauten ConfigParser angeschaut... Dumm dabei ist, wenn Fehler in der Config-Datei sind (z.B. fehlende Angaben) dann schlägt immer ein Traceback zum Anwender durch...
Deswegen hab ich mir eine "Hilfs"-Klasse ausgedacht, die "normale" Fehlermeldungen ausspuckt:
Code: Alles auswählen
import sys, os, ConfigParser
config_file = "MeineTolleKonfigurationsDatei.conf"
class Parser:
def __init__( self ):
self.current_section = ""
if not os.path.isfile( config_file ):
self.Fehler( "file not found!" )
self.cfg = ConfigParser.RawConfigParser()
self.cfg.read( config_file )
def set_section( self, section ):
self.current_section = section
def get( self, option, item_type = "str" ):
self.check( option )
if item_type == "str":
return self.cfg.get( self.current_section, option )
elif item_type == "int":
return self.cfg.getint( self.current_section, option )
def check( self, option ):
if not self.cfg.has_section( self.current_section ):
self.error( "section '[%s]' not found!" % self.current_section )
if not self.cfg.has_option( self.current_section, option ):
self.error( "in section '[%s]' option '%s' not found!" %
(self.current_section, option) )
def error( self, txt ):
print "error in Config File '%s':" % config_file
print txt
sys.exit()
Verfasst: Dienstag 8. März 2005, 23:33
von BlackJack
Es wäre wohl sinnvoller einfach die Ausnahmen zu behandeln statt selbst zu prüfen was sowieso schon geprüft wird um eben die Ausnahmen zu erzeugen.
Und möchte man wirklich das ein Programm jedes mal komplett abbricht nur weil ein Wert nicht in der Datei steht? Es gibt doch sicher viele Einstellungen für die man eine sinnvolle Voreinstellung in das Programm einbauen kann.
Die check()-Methode würde ich mir jedenfalls komplett sparen und einfach in get() auf die entsprechenden Ausnahmen reagieren.
Verfasst: Mittwoch 9. März 2005, 08:14
von jens
Naja, ich dachte vorher-checken ist sinnvoller als exceptions Abzufangen... Damit habe ich auch einen kürzeren Code, weil ich check() nur einmal aufrufen muß...
Natürlich sind immer noch exceptions Möglich, z.B. wenn ein getint() ausgeführt wird aber keine Zahl vorliegt...
Mit Vorgabewerten ist mit glaub ich zu kompliziert

Verfasst: Freitag 11. März 2005, 23:52
von BlackJack
Voher prüfen ist eher "unpythonic". Lies mal die Erklärung zu
EAFP im
Glossar vom Tutorial von der Python-Doku.
Empfohlener Stil ist es davon auszugehen das alles klappt und mit try/except Abzufangen was nicht funktioniert hat. Und der ConfigParser hat extra zwei schöne Ausnahmen für nicht vorhandene Abschnitte und Optionen.
Kann man z.B. so nutzen:
Code: Alles auswählen
#!/usr/bin/env python
import os, sys, new
from ConfigParser import RawConfigParser, NoSectionError, NoOptionError
class Parser:
def __init__(self, filename, defaults=None):
self.current_section = None
self.filename = filename
if not os.path.isfile(filename):
raise IOError('File %r does not exist.' % filename)
self.config = RawConfigParser(defaults)
self.config.read(filename)
# Create self.get*() methods.
for getter_name in ['get' + item_type
for item_type in ('', 'boolean', 'float', 'int')]:
get_method = getattr(self.config, getter_name)
setattr(self, getter_name,
new.instancemethod(self._getter_factory(get_method),
self, self.__class__))
def set_section(self, section_name):
self.current_section = section_name
def _getter_factory(self, get_method):
"""Wraps exception handling around `get_method`."""
def getter(self, option):
try:
return get_method(self.current_section, option)
except (NoSectionError, NoOptionError), error:
print 'Error in config file %r,' % self.filename
print 'section [%s], option %r' % (self.current_section, option)
print error
sys.exit(1)
return getter
Die Parser-Objekte haben auch gleich alle get*()-Methoden, die auch ein ConfigParser hat. Die werden in der __init__() dynamisch erzeugt. Python ist toll.

Verfasst: Donnerstag 21. April 2005, 09:16
von JC
Hui, das mit dem EAFP wusste ich gar nicht...gefällt mir aber irgendwie.
Vor allem, weil ich grad an der Uni nen Java-Einführungskurs mache...das ist doch sehr anders.
Hast du zufällig noch mehr Ressourcen, BlackJack? Ich würd mich gern mal informieren was EAFP oder "pythonic style" genau sind.
mfg
JC
Verfasst: Donnerstag 21. April 2005, 22:13
von BlackJack
EAFP steht ja im genannten Glossar. Ansonsten ist mir keine gesammelte Doku bekannt, die "pythonic" erklärt. Vieles bekommt man in der englischen Newsgroup mit, wo auch ein paar Programmierer aktiv sind, die die Standardbibliothek mit entwickeln und/oder die Distribution zusammenstellen.
Im Python Interpreter ``import this`` eingeben, verrät auch ein wenig filosofisches (schreibt man das jetzt so?

)
Verfasst: Freitag 22. April 2005, 12:57
von Leonidas
BlackJack hat geschrieben:Im Python Interpreter ``import this`` eingeben, verrät auch ein wenig filosofisches (schreibt man das jetzt so?

)
Nein, ich denke es heißt "philosophisch", aber ich bin eher naturwissenschaftlich veranlagt. *g*