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:

Der ConfigHandler

Beitragvon roschi » Freitag 10. Oktober 2008, 20:06

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
Fuer Alle, die in Python einsteigen wollen, kann ich das Buch A Byte of Python nur waermstens empfehlen!
BlackJack

Beitragvon BlackJack » Freitag 10. Oktober 2008, 20:27

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:

Beitragvon roschi » Freitag 10. Oktober 2008, 23:20

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 :)
Fuer Alle, die in Python einsteigen wollen, kann ich das Buch A Byte of Python nur waermstens empfehlen!
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5554
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Telfs (Tirol)
Kontaktdaten:

Beitragvon gerold » Samstag 11. Oktober 2008, 11:30

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

Beitragvon BlackJack » Samstag 11. Oktober 2008, 11:40

@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

Beitragvon Trundle » Samstag 11. Oktober 2008, 22:52

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:

Beitragvon roschi » Montag 13. Oktober 2008, 10:44

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
Fuer Alle, die in Python einsteigen wollen, kann ich das Buch A Byte of Python nur waermstens empfehlen!
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Beitragvon fred.reichbier » Montag 13. Oktober 2008, 11:10

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

Gruß Fred
BlackJack

Beitragvon BlackJack » Montag 13. Oktober 2008, 12:58

@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:

Beitragvon roschi » Dienstag 14. Oktober 2008, 14:00

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
Fuer Alle, die in Python einsteigen wollen, kann ich das Buch A Byte of Python nur waermstens empfehlen!
fred.reichbier
User
Beiträge: 155
Registriert: Freitag 29. Dezember 2006, 18:27

Beitragvon fred.reichbier » Dienstag 14. Oktober 2008, 14:03

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

Beitragvon roschi » Dienstag 14. Oktober 2008, 14:13

hallo!

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

mfg
roschi
Fuer Alle, die in Python einsteigen wollen, kann ich das Buch A Byte of Python nur waermstens empfehlen!
lunar

Beitragvon lunar » Dienstag 14. Oktober 2008, 17:11

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:

Beitragvon roschi » Dienstag 14. Oktober 2008, 19:26

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
Fuer Alle, die in Python einsteigen wollen, kann ich das Buch A Byte of Python nur waermstens empfehlen!
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 14. Oktober 2008, 20:06

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 Modvoice

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder