Der ConfigHandler

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

Der 'ConfigHandler' ist meiner meinung nach besser als der 'ConfigParser' aus der stdlib. er laesst sich einfacher (auch nur meiner meinung nach) bedienen.

schaut ihn euch doch mal an.
ich denke, der eine oder andere wird ihn auch als ganz nuetzlich befinden und vielleicht verwenden.

und hier gibts ihn:
http://python-tools.ath.cx/scripts/ConfigHandler/

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
BlackJack

Der Quelltext ist ziemlich unübersichtlich wegen der geringen Einrückung und das oft einzeilige Blöcke nicht in einer eigenen Zeile stehen.

Der Code selber ist furchtbar *umständlich*. Und er funktioniert nicht richtig. Kleiner "round trip", also auslesen und wieder schreiben, von dieser Datei:

Code: Alles auswählen

[B]
b = 1

[A]
a = 2

[C]
c = 3
liefert das hier:

Code: Alles auswählen

[A]
[C]
c = 3
[B]
b = 1
Aus

Code: Alles auswählen

[A]
foo = e = m*c^2
wird:

Code: Alles auswählen

[A]
foo = e
Und das hier:

Code: Alles auswählen

[A]
foo = [bar]
führt zu einer Ausnahme:

Code: Alles auswählen

Traceback (most recent call last):
  File "ConfigHandler.py", line 98, in <module>
    config = Config(open('test.ini'))
  File "ConfigHandler.py", line 64, in __init__
    self[section] = self._get_section_content(section)
  File "ConfigHandler.py", line 77, in _get_section_content
    % self.filecontent[startpos:endpos])
__main__.InvalidConfigError: Invalid section in config:
[A]
foo =
Ürigends sind alle '\' zum Fortsetzen einer Zeile überflüssig. Solange noch eine Klammer "offen" ist, braucht man die nicht.
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo BlackJack!

oh mein gott!
ich weiß im moment auch noch nicht woran es liegt...
aber es scheint nur bei deiner .ini nicht zu funktionieren.
ich habe eine aehnliche: :)

Code: Alles auswählen

[keks]
bla = blu

[asdf nessnu]
muh = maeh

[dewewed utztuz]
xyzs = qqq
mfg
roschi

PS: wenn ich weiß, woran es liegt, dann melde ich mich wieder!
PS: upps, ich habe vergessen 'reindent' drueberlaufen zu lassen :( naechstes mal denk ich drann, und der code der jetzt zum download bereit steht (den aber sicherlich aufgrund seiner fehler niemand haben moechte), ist jetzt auch PEP-8-isch eingerueckt :)
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo roschi!

Vielleicht ist das hier http://www.voidspace.org.uk/python/configobj.html etwas für dich.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
BlackJack

@roschi: Warum er bei mir den Inhalt von `[A]` "verschluckt" habe ich nicht nachvollzogen, aber Gleichheitszeichen und Text in eckigen Klammern in Werten, kann Dein Parser grundsätzlich nicht.
Benutzeravatar
Trundle
User
Beiträge: 591
Registriert: Dienstag 3. Juli 2007, 16:45

Die Sektion wird verschluckt, weil das Slicing einfach falsch ist, da zu `endpos` noch `startpos` addiert werden müsste.
"Der Dumme erwartet viel. Der Denkende sagt wenig." ("Herr Keuner" -- Bertolt Brecht)
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

danke fuer die hilfen!

@Trundle:
super, daran hatte ich nicht gedacht.
jetzt verschluckt er nichts mehr!

@BlackJack:
ja, jetzt kann er auch '=' und '[text]'.
allerdings muesste ich noch dieses pattern hier:

Code: Alles auswählen

r"\[(.*)\]"
so veraendern, dass es nur passt, wenn [xyz] allein in einer zeile steht.
koennte mir dabei vielleicht jemand helfen?
wenn ich '^' und '$' reinbaue (zeilenanfang und zeilenende), dann klappt es gar nicht.

@gerold:
naja, also 'ConfigObj' finde ich ziemlich groß, 70 KB!
wenn ich den in ein programm einbauen moechte, dann ist der ja groeßer als das programm selber. :)

so, bald wird er fertig sein! :D

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Vielleicht funktioniert das mit ^ und $, wenn du re.MULTILINE in die Flags aufnimmst?

Gruß Fred
BlackJack

@roschi: Ich würde da gar nicht mit regulären Ausdrücken arbeiten. Ob eine Zeile ein Sektionsanfang ist, kann man auch mit folgender Funktion feststellen:

Code: Alles auswählen

def is_section_header(line):
    line = line.strip()
    return line.startswith('[') and line.endswith(']')
Schmeiss den Quelltext komplett weg und schreib ihn neu, ohne `re` und weniger umständlich. Alleine der Anfang ist schon krank: Die Datei komplett einlesen, an Zeilenumbrüchen ausspalten, Leerzeilen rausfiltern und dann wieder zu einem grossen Klumpen zusammensetzen aus dem dann mit regulären Ausdrücken die Sektionen heraus gepopelt werden, ist megaumständlich.

Mal was ganz einfaches, ohne `re`\s:

Code: Alles auswählen

import sys
from collections import defaultdict


def is_ignorable(line):
    return not line or line.startswith(('#', ';'))


def is_section_header(line):
    line = line.strip()
    return line.startswith('[') and line.endswith(']')


def read_ini(lines):
    result = defaultdict(dict)
    section = None
    for line in lines:
        line = line.strip()
        if not is_ignorable(line):
            if is_section_header(line):
                section = line[1:-1]
            else:
                key, value = line.split('=', 1)
                key = key.rstrip()
                value = value.lstrip()
                result[section][key] = value
    return result


def write_ini(config, out_file):
    for section, values in sorted(config.iteritems()):
        out_file.write('[%s]\n' % section)
        out_file.writelines('%s = %s\n' % item
                            for item in sorted(values.iteritems()))
        out_file.write('\n')
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

@BlackJack & fred.reichbier:
MERCI!
ich habe deine vorschlaege uebernommen, und es klappt einwandfrei!

vielen, vielen dank!

der 'ConfigHandler' ist jetzt in version 1 fertig.
download:
http://python-tools.ath.cx/scripts/ConfigHandler/

ich hoffe, er wird dem ein oder anderen nuetzlich sein. :D

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

@fred.reichbier:
sorry, hab mich vertan - jetzt gehts.

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
lunar

roschi hat geschrieben:@gerold:
naja, also 'ConfigObj' finde ich ziemlich groß, 70 KB!
wenn ich den in ein programm einbauen moechte, dann ist der ja groeßer als das programm selber. :)
Wenn die geringe Größe der einzige Vorteil deines Moduls ist, dann ist das Modul eher überflüssig. In welcher Umgebung (vom Embedding mal abgesehen) ist der Unterschied zwischen 70 Kb und 7 Kb denn noch relevant?
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

@lunar:
naja, vielleicht, wenn ich es zum beispiel mit pyinstaller in eine .exe packe? normale consolenprogramme haben durchschnittlich 3 mb, meine ich mich zu erinnern. da faellt es schon auf, wenn man mehrere riesenmodule verwendet. zumal es ja - wie man sieht - auch kleinr geht.

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

roschi hat geschrieben:naja, vielleicht, wenn ich es zum beispiel mit pyinstaller in eine .exe packe? normale consolenprogramme haben durchschnittlich 3 mb, meine ich mich zu erinnern. da faellt es schon auf, wenn man mehrere riesenmodule verwendet. zumal es ja - wie man sieht - auch kleinr geht.
Ja, der Unterschied zwischen 3072 Kilobyte und 3135 Kilobyte ist natürlich bedeutend. Die 63 Kilobyte die dazwischenliegen machen immerhin einen Unterschied von 2,05078125% aus, das ist doch durchaus beachtlich.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

hallo!

@Leonidas:
och mensch *noergl* musst du denn immer so korrekt sein :)
ja, gut, es ist vielleicht doch nicht so schrecklich.
vielleicht sollte ich sagen: "es macht doch viel mehr spaß, etwas selber zu schreiben, wenn man es schon kann, anstatt irgendwas fertiges zu nehmen" :)

mfg
roschi

PS:
wenn die .exe 3072 kilobyte groß ist, und man dann noch meinen ConfigHandler draufpackt, dann sind das etwa 3074,87 kilobyte (0,09342447916666666666666666667% mehr). mit ConfigObj sind das dann etwa 3158,5 kilobyte (2,815755208333333333333333333%). differenz: 83,63 kilobyte (2,722330729166666666666666666% von 3072). man koennte das ja auch noch byte-genau machen, aber dazu habe ich im moment keine lust.
:lol: :) :lol:
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

roschi hat geschrieben:vielleicht sollte ich sagen: "es macht doch viel mehr spaß, etwas selber zu schreiben, wenn man es schon kann, anstatt irgendwas fertiges zu nehmen" :)
Ja, der Grund ist wohl eher einleuchtend, auch wenn ich es sinnvoller fände etwas neues zu machen wass es nicht schon doppelt und dreifach gibt ;) (Allerdings gebe ich zu, dass ich auch schon komplett überflüssige Sachen geschrieben habe)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

ja, du hast recht, vielleicht sollte man was exotischeres programmieren...
ich hab auch schon mal so was aehnliches wie 'Lanshark' geschrieben, nur mit dem Unterschied, dass noch ein FTP-Server dabei ist und die GUI mit wx gemacht wurde.

btw: warum spricht man 'wx' eigendlich wie 'vx' aus? eigendlich muesste es doch 'dabbelju ex' heißen. :?

mfg
roschi
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

roschi hat geschrieben:btw: warum spricht man 'wx' eigendlich wie 'vx' aus? eigendlich muesste es doch 'dabbelju ex' heißen. :?
Wer spricht wx so aus?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

heißt das nicht 'wie ex peiten'?

ich dachte, ich hab das ueberall so gehoert... :? :? :?
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Antworten