Konfigurationsdatei casesensitiv auslesen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Woodstock
User
Beiträge: 2
Registriert: Mittwoch 4. Juli 2007, 19:33

Hallo!

[Randbemerkung]
Ich versuche gerade, mich in Python einzuarbeiten, und hole mir dabei eine blutige Nase.

Ich dachte, ich könnte das Modul ConfigParser zum Auslesen meiner Konfigurationsdatei nehmen, aber leider habe ich (nachdem ich nach studenlangem probieren überhaupt erst funktionsfähigen Code hatte) festgestellt, daß mir ConfigParser.Items('Section') Kleinbuchstaben zurückgibt. Das kann ich leider nicht gebrauchen (wieso steht das nicht in der Doku?)

Die Datei sieht z.B. so aus
[Symbols]
H = 1.0079
O = 15.996
cp = C5H5

etc.

Ich wollte alle Items, die in der Section "Symbols" auftauchen in ein Dictionary lesen. Das funktionert inzwischen auch, aber die Groß-Kleinschreibung geht verloren. Für mein Zwecke muß sie aber erhalten bleiben!

Kennt jemand einen Weg, mit dem man die Groß-Kleinschreibung erhalten kann oder vielleicht ein anderes Modul, das diese Aufgabe besser löst als ConfigParser? Oder muß ich mir gar eine eigene Funktion dafür schreiben?
In der Doku zu ConfigParser steht:
Default values can be specified by passing them into the ConfigParser constructor as a dictionary. Additional defaults may be passed into the get() method which will override all others.
Ich habe das so verstanden, daß man auch der get-Methode einen Default-Wert übergeben kann. Kann mir jemand sagen wie das geht? Mir ist das nicht gelungen, und auch in der detaillierten Doku der get-Methode ist gar keine Rede mehr von Default-Werten.

Danke,
Woodstock
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Woodstock hat geschrieben:festgestellt, daß mir ConfigParser.Items('Section') Kleinbuchstaben zurückgibt.
[...]
die Groß-Kleinschreibung geht verloren. Für mein Zwecke muß sie aber erhalten bleiben!
Hallo Woodstock!

Willkommen im Python-Forum!

Vorab: In INI-Dateien sind Sektionsnamen und Optionsnamen unabhängig von der Groß-/Kleinschreibung. Das ist dem Verhalten der Windows-API-Funktionen "GetProfileString" und "GetPrivateProfileString" nachempfunden.
Wenn du also in deiner "INI"-Datei darauf rücksicht nimmst, dann entspricht das nicht mehr dem üblichen Verhalten.

Wie auch immer. Der Mensch brauch Übung, dass er nicht rostet. Deshalb habe ich hier ausnahmsweise ein fertiges Beispiel für dich:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

import os
from ConfigParser import SafeConfigParser
from ConfigParser import NoSectionError, NoOptionError
from textwrap import dedent


class SafeConfigParser_(SafeConfigParser):
    
    def get(self, section, option, raw=False, vars=None, default = None):
        """
        Überschreibt `get` mit einer Version, die einen Standardwert
        erlaubt
        """
        
        try:
            return SafeConfigParser.get(
                self, section, option, raw=False, vars=None
            )
        except (NoSectionError, NoOptionError):
            return default

    
    def optionxform(self, optionstr):
        """
        Überschreibt `optionxform` mit einer Version, die nicht mehr alle
        Optionsnamen mit `lower()` umwandelt.
        """
        
        return optionstr
    
    
    def _get(self, section, conv, option, default = None):
        """
        Überschreibt `_get` mit einer Version, die einen Standardwert
        erlaubt.
        """
        
        return conv(self.get(section, option, default = default))
    
    
    def getint(self, section, option, default = None):
        """
        Überschreibt `getint` mit einer Version, die einen Standardwert
        erlaubt
        """
        
        return self._get(section, int, option, default = default)
    
    
    def getfloat(self, section, option, default = None):
        """
        Überschreibt `getfloat` mit einer Version, die einen Standardwert
        erlaubt
        """
        
        return self._get(section, float, option, default = default)


def main():
    """Testen"""
    
    INIFILE = "my_inifile.ini"
    SYMBOLS = "Symbols"
    
    # Zum Testen, INI-Datei erstellen
    if not os.path.isfile(INIFILE):
        inistring = dedent(
            """
            [%s]
            H = 1.0079
            O = 15.996
            cp = C5H5 
            """ % SYMBOLS
        )
        f = file("my_inifile.ini", "w")
        f.write(inistring)
        f.close()
    
    # Man achte auf den zusätzlichen Unterstrich
    ini = SafeConfigParser_()
    ini.read(INIFILE)
    
    print ini.sections() # ['Symbols']
    print ini.items(SYMBOLS) # [('cp', 'C5H5'), ('O', '15.996'), ('H', '1.0079')]
    print ini.get(SYMBOLS, "cp") # C5H5
    print ini.get(SYMBOLS, "CP") # None
    print ini.getfloat(SYMBOLS, "H") # 1.0079
    print ini.getfloat(SYMBOLS, "X", 5.3) # 5.3
    print ini.getint(SYMBOLS, "I", 10) # 10


if __name__ == "__main__":
    main()
Im Beispiel werden Teile der Klasse "SafeConfigParser" überschrieben, um das gewünschte Verhalten zu erzwingen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Woodstock
User
Beiträge: 2
Registriert: Mittwoch 4. Juli 2007, 19:33

gerold hat geschrieben:Vorab: In INI-Dateien sind Sektionsnamen und Optionsnamen unabhängig von der Groß-/Kleinschreibung. Das ist dem Verhalten der Windows-API-Funktionen "GetProfileString" und "GetPrivateProfileString" nachempfunden.
Ich benutze Windows schon eine ganze Weile nicht mehr, und in der Doku stand nicht genau wie sich ConfigParser verhält. Abgesehen davon hätte es mir nichts gesagt, wenn darin gestanden hätte, daß es "GetProfileString" und "GetPrivateProfileString" nachbildet.
Wie auch immer. Der Mensch braucht Übung, dass er nicht rostet. Deshalb habe ich hier ausnahmsweise ein fertiges Beispiel für dich:
[Beispiel]

Danke.
Ja, der Mensch braucht Übung, auch im das Zeug zu lernen. Ich dachte mir, daß ich Python lerne, damit ich besser mit scipy oder matplotlib zurechtkomme. Dazu wollte ich eben ein kleines Programm schreiben, weil ich mir einbildete, daß es sich an einem konkreten Projekt leichter lernt als in Büchern die Beispiele nachzuvollziehen.
Leider stoße ich auf mehr Hürden als ich vermutet hatte. Insbesondere mit der Objektorientierung stehe ich noch auf Kriegsfuß.

Danke für Dein Beispiel. Dann werde ich mich jetzt mal ans Nachvollziehen machen.

Viele Grüße,
Wookstock
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hallo Woodstock, willkommen im Forum,
Woodstock hat geschrieben:Ja, der Mensch braucht Übung, auch im das Zeug zu lernen. Ich dachte mir, daß ich Python lerne, damit ich besser mit scipy oder matplotlib zurechtkomme. Dazu wollte ich eben ein kleines Programm schreiben, weil ich mir einbildete, daß es sich an einem konkreten Projekt leichter lernt als in Büchern die Beispiele nachzuvollziehen.
Leider stoße ich auf mehr Hürden als ich vermutet hatte. Insbesondere mit der Objektorientierung stehe ich noch auf Kriegsfuß.
Du hast ganz recht - mit einem Projekt Python zu lernen kann durchaus einfacher sein, weil man eben an seinen Problemen wächst. Ansonsten ist das OOP in Python kein Hexenwerk (wenn man man auf Metamagie etc. verzichtet) sondern eine ziemlich einfach verständliche Sache. Jedoch solltest du beim Einsatz von OOP achten, ob es auch Sinn macht, Klassen zu nutzen oder ob du Klassen nur um der Klassen willen einsetzt. Dies ist auch eine sehr wichtige Sache, zu merken dass Klassen ein Mittel zum Zweck sind und kein Selbstzweck.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten