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
ConfigParser -> Verschiedene Sections in verschiedene Dateie
Hallo.
Sebastian
Es heißt übrigens "Klasse" und nicht "Classe" oder "Class".
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:Deshalb wollte ich "einfach" von der SaveConfigParser Classe erben und dann per __get__ auf das eigentlich verwendete SafeConfigParser Objekt umzuleiten.
Manche Dinge kann man ganz einfach ausprobieren, dann stellen sich viele Fragen erst gar nicht und Probleme verschwinden dannp90 hat geschrieben:Aber __get__ geht doch nur für Attribute und nicht für Methoden oder?
Sebastian
Es heißt übrigens "Klasse" und nicht "Classe" oder "Class".
Das Leben ist wie ein Tennisball.
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.
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.
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.
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.
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:
Innerhalb von func hast du nun Zugriff auf value und auf das self der config-Instanz und kannst dich beliebig austoben.
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
Das Leben ist wie ein Tennisball.
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.
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.