ConfigParser -> Verschiedene Sections in verschiedene Dateie

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
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

und noch eine Frage die mich schon eine Weile beschäftigt.
Ich hab in meinem Programm zwei Instanzen eines SaveConfigParser objekts.
Eins für meine Config, die zweite für State Informationen. Zu Beginn wird aus der Config der State generiert und nur der State wird immer auf die Platte geschrieben. Nun brauche ich aber sowohl Config als auch State immer und das getrennt durchzuschleppen ist irgendwie nicht so schön.
Deshalb möchte ich eine Class schreiben die eine Weiche repräsentiert. Die Idee ist, das beim lesen immer die Config genommen wird wenn es im State nichts gibt, alles was aber gesetzt wird wird nur in den State geschrieben.
Ich kann jetzt natürlich hingehen und einfach alle Methoden des SaveConfigParser Objekts erzeugen und dann da jeweils eine Weiche einbauen. Was ja irgendwie etwas doof ist weil ich dann ja genau auf eine Version festgelegt bin und jedes mal nach schreiben muss wenn wieder mal eine neue Methode dazugekommen ist. Deshalb wollte ich "einfach" von der SaveConfigParser Classe erben und dann per __get__ auf das eigentlich verwendete SafeConfigParser Objekt umzuleiten.
Aber __get__ geht doch nur für Attribute und nicht für Methoden oder?
Wie kann ich das ganze den für Methoden machen?

Euch allen noch einen schönen Mittag!

p90
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.
p90 hat geschrieben:Deshalb wollte ich "einfach" von der SaveConfigParser Classe erben und dann per __get__ auf das eigentlich verwendete SafeConfigParser Objekt umzuleiten.
Das hört sich für mich nach einer etwas abenteuerlichen Idee an. Eine extra Klasse, welche zwei SafeConfigParser-Instanzen enthält (Komposition), scheint mir hier geschickter zu sein. Das sieht hier nicht nach einer ist-ein-Beziehung aus. Ich mag mich aber auch täsuchen, deine Beschreibung finde ich etwas wirr und ich bin ein wenig übermüdet. Schlechte Kombination ^^
p90 hat geschrieben:Aber __get__ geht doch nur für Attribute und nicht für Methoden oder?
Manche Dinge kann man ganz einfach ausprobieren, dann stellen sich viele Fragen erst gar nicht und Probleme verschwinden dann ;-)

Sebastian

Es heißt übrigens "Klasse" und nicht "Classe" oder "Class".
Das Leben ist wie ein Tennisball.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,

erstmal Danke für die Antwort, bin leider manchmal etwas wirr :(
Aber egal, du hast genau verstanden was ich wollte ^^
Ich wusste bloß nicht, dass es so etwas wie __getattr__ gibt, dass aufgerufen wird wenn auf normalem Wege das Attribut nicht gefunden werden konnte.
So weit so gut.

Code: Alles auswählen

class config:
	def __init__(self):
                #snipp
		self.config = ConfigParser.SafeConfigParser()
		self.config.read(os.path.join(basepath, 'config.cfg'))
		self.state = ConfigParser.SafeConfigParser()
		self.state.read(config.get("main", "statefile"))
                #snipp
	def __getattr__:(self, name):
		if "set" in name:
			return self.state.__getattr__(name)
		else:
			try:
				value = self.state.__getattr__(name)
                                #hier fehlt noch was
                                #weil eigentlich muss ich hier self.state.__getattr__(name) aufrufen und gucken ob ich eine exception bekomme oder nicht. Wenn ja muss ich die Daten nicht aus dem State sondern aus der Config hohlen. Aber ich habe die Argumente für den Aufruf ja gar nicht, die kommen ja erst später. 
Nur funktioniert das halt an der markierten stelle nicht, da getattr ja nur den Namen des Attributes bekommt und gar nicht weiß das es eine Methode ist.
Muss ich vlt doch was anderes machen?
Hatte mir überlegt, dass man ja auch das __dict__ meiner Klasse mit den entsprechenden Funktionen einer SaveConfigParser Klasse ausstatten könnte und in diesen Funktionen halt die Weiche einbaut. Dann würde das ganze immer noch dynamisch zur Laufzeit passieren und neue Methoden von SaveConfigParser würden ohne neuen Code nutzbar gemacht.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Gerade haben sich einige Wirrungen bei mir aufgelöst. Ich hatte bei deinem Beitrag die ganze Zeit __getattr__ gelsen, obwohl du __get__ geschrieben hattest. Das erklärt natürlich ein wenig die Schwierigkeit. Vielleicht erst noch drei Anmerkungen zu deinem Code:

Python hat eine getattr-Funktion, die solltest du dir mal anschauen. Dann sparst du dir den Umweg über ``self.__state-__getattr__``.

Und dann sieht der Test ``"set" in name`` noch ein wenig verdächtig aus. Ich vermute mal, dass du eigentlich ``name.startswith("set")`` meinst. Dann sollte man das ganze Konstrukt aber durch Properties ersetzen, da set-Methoden bei Python eher unüblich sind. Das nur mal so als Vermutung.

Außerdem würde ich nicht alles "config" nennen. Bei dir sehe ich zwar keine Konflikte, aber es ist schon sehr unübersichtlich, wenn sowohl die Klasse, als auch ein Attribut dieser, den selben Namen tragen.

Jetzt aber zu deinem eigentlichen Problem. Im Prinzip sollte das ausreichen:

Code: Alles auswählen

def __getattr__:(self, name):
    value = getattr(self.state, name)

    if "set" in name:
        return value
    else:
        def func(*args, **kwds):
            ...
        
        return func
Innerhalb von func hast du nun Zugriff auf value und auf das self der config-Instanz und kannst dich beliebig austoben.
Das Leben ist wie ein Tennisball.
p90
User
Beiträge: 198
Registriert: Donnerstag 22. Juli 2010, 17:30

Hi,
also das mit dem "set" in hatte ich einfach genommen weil alle Methoden die einen Wert setzen im ConfigParser Modul mit einem set beginnen aber startswith sollte auch gehen.

2.
Ich habe das Problem anscheinend nicht genau genug beschrieben.
Was ich ja brauche ist dies:
1. Jeder schreibvorgang (soll heißen jede Methode die mit einem set beginnt) soll mit der Methode des states ersetzt werden, schließlich will ich nicht in meine Menschen gemachte Config schreiben.
2. Wenn ich lese haben Werte aus state eine höhere priorität als die aus der Config weil diese ja neuer sind. -> Ich muss zuerst versuchen die Daten aus dem state zu lesen, schlägt dies fehl weil nicht da muss ich diese aus der Config nehmen.
AFAIK geht dies bei ConfigParser nur so, dass man entweder einfach versucht den Wert zu lesen -> wenn er nicht da ist wird ein ConfigParser.NoSectionError geworfen oder indem man die Methode ConfigParser.hasSection verwendet. Diese gibt dann True oder False zurück. Das Problem ist, ich muss dazu ja die section und den name wissen. __getattr__ bekommt aber nur den Namen des Attributes und erst nachdem das Attribut zurückgegeben worden ist wird es zum Ausführen mit den von mir gesuchten Argumenten zusammen gebracht. __getattr__ kann dieses Problem also leider nicht lösen (ist aber eine sehr coole Funktion die ich bisher noch nicht kannte). Ich muss meine Weiche also an einer anderen Stelle einbauen und zwar da wo die Methode aufgerufen wird.
Antworten