Hi
In welchem Zusammenhang brauchst du solch ein verhalten?
Irgendwie hab ich das Gefühl, dass man das ganze anders gestalten könnte.
Gruss
Vereinfachung immerwiederkehrender Ausdruck
Ich parse eine bestimmte Dateistruktur. Ähnlich zu INI-Dateien gibt es darin Sektionen, Schlüssel und Werte, also z.B. sowas hier:rayo hat geschrieben:In welchem Zusammenhang brauchst du solch ein verhalten?
Code: Alles auswählen
[Foo]
spam=eggs
Ich gehe also jede Zeile der Datei durch und prüfe deren Aufbau mittels RegExe. Beispiel:
Code: Alles auswählen
reSection = re.compile(r"^\[([^\]]*)\]$")
reKeyValue = re.compile(r"^([^\=]+)\=(.*)$")
def is_section(line):
m = reSection.search(line)
if m:
# return section name
return m.group(1)
else:
return False
def is_key_value(line):
m = reKeyValue.search(line)
if m:
# return key and value as a tuple
return m.groups()
else:
return False
Code: Alles auswählen
for line in lines:
# check if the line is a section
section = is_section(line)
if section:
# create a new section object and submit the name
so = SectionObject(section)
# register the section at the parser
myParser.register_section(so)
else:
# check if the line is a key/value pair
keyval = is_key_value(line)
if keyval and s:
# parse key only if a section object has already been created
key, value = keyval
# create a new key object and submit the value if any
ko = KeyObject(key)
if value:
ko.value = value
# append the key object to the last section
s.add_key(ko)
else:
# more options later...
more = is_more(line)
# ...
else:
# this line is not interesting, so ignore it
pass
-
- User
- Beiträge: 773
- Registriert: Mittwoch 5. November 2003, 18:06
- Wohnort: Schweiz
- Kontaktdaten:
Hi
Also ich würde Funktionen schreiben (z.B. handleSection, ...) und eine Liste mit [(is_section, handleSection), ...] machen und mit einer schleife durchgehen.
Da du dass aber nicht möchtest würde ich dir vorher noch continue nahelegen, damit gibts keine verschachtelungen
Gruss
Also ich würde Funktionen schreiben (z.B. handleSection, ...) und eine Liste mit [(is_section, handleSection), ...] machen und mit einer schleife durchgehen.
Da du dass aber nicht möchtest würde ich dir vorher noch continue nahelegen, damit gibts keine verschachtelungen
Code: Alles auswählen
for line in lines:
# check if the line is a section
section = is_section(line)
if section:
# create a new section object and submit the name
so = SectionObject(section)
# register the section at the parser
myParser.register_section(so)
continue
keyval = is_key_value(line)
if keyval and s:
# parse key only if a section object has already been created
key, value = keyval
# create a new key object and submit the value if any
ko = KeyObject(key)
if value:
ko.value = value
# append the key object to the last section
s.add_key(ko)
continue
# more options later...
more = is_more(line)
if more:
continue
#code ohne match
Das Folgende ist zum Beispiel eine recht allgemeingültige Lösung für das Problem. Über die Verwendug von "break" darf sich natürlich ausgibig ausgelassen werden.
EDIT: Ach ja, die "return ..." geben natürlich "True" oder "False" zurück. Alternativ könnte man auch gleich eine Instanz erzeugen und registrieren, sieht dann aber irgendwie seltsam aus.
Code: Alles auswählen
class IniComponent:
@staticmethod
def test(expr)
assert 0, "implement me!"
def register(self, parser):
assert 0, "implement me!"
class Section:
@staticmethod
def test(expr):
#test here
return ...
def __init__(self, line):
#...
def register(self, parser):
parser.register_section(self)
class KeyValue:
@staticmethod
def test(expr):
#test here
return ...
def __init__(self, line):
#...
def register(self, parser):
parser.register_key_value(self)
for line in lines:
for i in [Section, KeyValue]:
if i.test(line):
i(line).register(parser)
break
else:
print "invalid component"
Oha, da gibt's gleich noch ein paar Fragen zum Code
Insgesamt aber auch keine schlechte Idee, gefällt mir! Ich lass mir das mal durch den Kopf gehen.
Was macht `@staticmethod` und was bewirkt die Zeile mit `assert`?EyDu hat geschrieben:Code: Alles auswählen
class IniComponent: @staticmethod def test(expr) assert 0, "implement me!"
Insgesamt aber auch keine schlechte Idee, gefällt mir! Ich lass mir das mal durch den Kopf gehen.
Eine Methode die mit "staticmethod" gekennzeichnet ist, kann ohne eine konkrete Instanz der Klasse aufgerufen werden. Da sollten sich genug Informationen in Texten über OOP finden lassen. Sonst gibt es hier auch noch eine kurze Beschreibung (unter "staticmethod"): HIER.droptix hat geschrieben: Was macht `@staticmethod`
Schau dir das mal in der Doku an. Hier wird es dafür verwendet, um zu prüfen ob die methoden auch tatsächlich in den geerbten Klassen implementiert wurden.droptix hat geschrieben: und was bewirkt die Zeile mit `assert`?
Naja, ist ja nicht meine Idee In der OOP ein gängiger Weg.droptix hat geschrieben: Insgesamt aber auch keine schlechte Idee, gefällt mir! Ich lass mir das mal durch den Kopf gehen.
EDIT: Das böse Worte "eigentlich" entfernt
1. Hier wäre eher ein raisen der ``NotImplementedError`` Exception angebracht.EyDu hat geschrieben:Code: Alles auswählen
class IniComponent: @staticmethod def test(expr) assert 0, "implement me!" def register(self, parser): assert 0, "implement me!" ...
Code: Alles auswählen
@staticmethod
def test(expr)
raise NotImplementedError
def register(self, parser):
raise NotImplementedError
2. ``assert``s werden zur zusicherung benutzt. Damit teste man Sachen die unmöglich passieren können/dürfen. Falls doch eine ``assert`` Bedingung ``False`` zurückgibt, dann kann von einem Programmfehler (Programmierfehler) ausgegangen werden.
Sehr guter Thread zu dem Thema: http://www.python-forum.de/post-53814.html#53814
IMHO würde ich daher eine nicht implementierte Funktion/Methode, nicht in diese Kategorie werfen und daher lieber die standard Exception ``NotImplementedError`` für solch eine Situation auslösen.
Stimmt, da hatte ich nicht dran gedacht.sape hat geschrieben: 1. Hier wäre eher ein raisen der ``NotImplementedError`` Exception angebracht.
Und das ist es ja auch. Aber da es eine entsprechene Exception gibt, sollte man diese auch nutzen.sape hat geschrieben: 2. ``assert``s werden zur zusicherung benutzt. Damit teste man Sachen die unmöglich passieren können/dürfen. Falls doch eine ``assert`` Bedingung ``False`` zurückgibt, dann kann von einem Programmfehler (Programmierfehler) ausgegangen werden.