SetSourceRGBA erbt von Diagram und Diagram hat eine __init__, die aufgerufen wird.
`cr = self.cr = cairo.Context(self.surface)` bewirkt, dass das Objekt sowol an das Objekt gebunden wird als auch als kurzer Name (cr) zur Verfügung steht. Da war wohl jemand zu faul immer self.cr zu schreiben.
Kleiner Bericht zum Umstieg von Sprache xy auf Python
Wenn die abgeleitete Klasse keine __init__-Methode hat, dann wird die der Basisklasse aufgerufen. Hätte die abgeleitete Klasse eine solche Methode so würde die der Basisklasse nur aufgerufen, wenn das in der abgeleiteten Klasse so programmiert wäre.mechanicalStore hat geschrieben: Wird durch diesen Aufruf automatisch die __init__ Methode der Basisklasse (Diagram) aufgerufen (ich frage, weil ich meine mich zu erinnern, dass irgendwo gesagt wurde, dass das nicht so ist und man sich selbst darum kümmern muss, dass der Konstruktor der Basisklasse aufgerufen wird)?
Nein. Zumindest ich sehe das nicht als problematisch an, sondern eher als das, was Objektorientierung mit ausmacht.mechanicalStore hat geschrieben:Ist es nicht sehr unsauber, im Konstruktor der Basisklasse in der Zeile ** eine Methode der erbenden Klasse aufzurufen?
Nein. cr ist nur im Konstruktor bekannt.mechanicalStore hat geschrieben: Bedeutet folgende Zeile im Kontruktordass self.cr eine Instanzvariable und cr eine Klassenvariable ist?Code: Alles auswählen
cr = self.cr = cairo.Context(self.surface)
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Das mag sein, aber da man direkt Klassen von `Diagram` erstellen kann, finde ich das durchaus unsauber./me hat geschrieben:Nein. Zumindest ich sehe das nicht als problematisch an, sondern eher als das, was Objektorientierung mit ausmacht.mechanicalStore hat geschrieben:Ist es nicht sehr unsauber, im Konstruktor der Basisklasse in der Zeile ** eine Methode der erbenden Klasse aufzurufen?
IMHO sollte man ein `draw_dest` in `Diagram` erstellen, das einen `NotImplementedError` schmeisst oder vergleichbares.
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
Wieso sollte keine Instanzierung stattfinden? Wie sma schon schrieb, eine Klasse gibt, wenn man sie „wie eine Funktion aufruft“ eine Instanz von sich selbst zurück(das Verhalten ließe sich natürlich ändern, da Klassen auch nur Objekte wie alle anderen sind). Wie genau das geschieht, kann dir erstmal egal sein.mechanicalStore hat geschrieben:Frage zur letzten Zeile: Wird hier die Klasse tatsächlich "nur" als Funktion aufgerufen (da keine Instanzierung stattfindet)?
Jein, dass macht deine Klasse nur schlicht und ergreifend zu einer abstrakten Klasse. Aber wie schon geschrieben, wäre es besser, die Methode in der Basisklasse zu implementieren und einen NotImplementedError zu werfen, das macht die Fehlermeldungen aussagekräftiger bzw. man man ggf. besser auf den Fehler reagieren.Ist es nicht sehr unsauber, im Konstruktor der Basisklasse in der Zeile ** eine Methode der erbenden Klasse aufzurufen?
cr ist eine stinknormale lokale Variable. Es gibt keinen Grund, warum das nicht so sein sollte. Warumdass self.cr eine Instanzvariable und cr eine Klassenvariable ist? Falls ja, hätte man in dem Fall cr nicht auf der (Einrück)-Ebene im Hauptblock (also auf der Ebene, wo auch __init__ deklariert wurde) deklarieren müssen?Code: Alles auswählen
cr = self.cr = cairo.Context(self.surface)
Warum er das überhaupt macht, liegt daran, dass Attributzugriffe in Python relativ teuer sind. Wenn eine Funktion oft aufgerufen wird kann schon Zeit sparen, wenn man dort oft verwendete Attribute lokal „cached“. Man sollte das aber auch nicht überstrapazieren(premature optimization...)
Zuletzt geändert von Darii am Montag 4. Januar 2010, 21:05, insgesamt 4-mal geändert.
-
- User
- Beiträge: 111
- Registriert: Dienstag 29. Dezember 2009, 00:09
Wenn man die Klassen aber in einzelne Module trennen würde, wäre es doch im Sinne der Objektorientierung fatal, dass die Basisklasse mit dem Aufruf von drawTest abhängig davon wird, ob/dass eine Vererbung stattfindet, ob nun mit oder ohne NotImplementedError, oder?Jein, dass macht deine Klasse nur schlicht und ergreifend zu einer abstrakten Klasse. Aber wie schon geschrieben, wäre es besser, die Methode in der Basisklasse zu implementieren und einen NotImplementedError zu werfen, das macht die Fehlermeldungen aussagekräftiger bzw. man man ggf. besser auf den Fehler reagieren.Ist es nicht sehr unsauber, im Konstruktor der Basisklasse in der Zeile ** eine Methode der erbenden Klasse aufzurufen?
Ok, ich ging von Java (oder auch C#) aus, wo "lokale" Variablen innerhalb einer Klassendeklaration ein implizites "this." erhalten. Verglichen hiermit gäbe es dann self.cr doppelt. Aber da weicht Python wohl stark von ab (wie ja auch schon gesagt wurde, ist Java als Vergleich ungeeignet).cr ist eine stinknormale lokale Variable. Es gibt keinen Grund, warum das nicht so sein sollte. Warum er das überhaupt macht, liegt daran, dass Attributzugriffe in Python relativ teuer sind. Wenn eine Funktion oft aufgerufen wird kann schon Zeit sparen, wenn man dort oft verwendete Attribute lokal „cached“. Man sollte das aber auch nicht überstrapazieren(premature optimization...)dass self.cr eine Instanzvariable und cr eine Klassenvariable ist?Code: Alles auswählen
cr = self.cr = cairo.Context(self.surface)
Schönen Gruß
Nein, deswegen gibt es ja abstrakte Klassen/Methoden(auch in Java). Und seit Python 2.6 gibt es auch Möglichkeiten, das Ganze in geregelte Bahnen zu lenkenmechanicalStore hat geschrieben:Wenn man die Klassen aber in einzelne Module trennen würde, wäre es doch im Sinne der Objektorientierung fatal, dass die Basisklasse mit dem Aufruf von drawTest abhängig davon wird, ob/dass eine Vererbung stattfindet, ob nun mit oder ohne NotImplementedError, oder?
Nein das tun sie auch in Java oder C# nicht. Variablen die man in Methoden deklariert werden nicht automatisch Instanzvariablen.Ok, ich ging von Java (oder auch C#) aus, wo "lokale" Variablen innerhalb einer Klassendeklaration ein implizites "this." erhalten. Verglichen hiermit gäbe es dann self.cr doppelt. Aber da weicht Python wohl stark von ab (wie ja auch schon gesagt wurde, ist Java als Vergleich ungeeignet).
-
- User
- Beiträge: 111
- Registriert: Dienstag 29. Dezember 2009, 00:09
Sorry, was Methoden betrifft, hast Du natürlich Recht! Ich habe etwas durcheinander gebracht, ist doch recht ungewohnt, wenn keine Variable explizit deklariert wird. Gibt es bei Python ein "use strict" a'la Perl?Nein das tun sie auch in Java oder C# nicht. Variablen die man in Methoden deklariert werden nicht automatisch Instanzvariablen.
Schönen Gruß
@mechanicalStore: Nein so etwas wie "use strict" gibt es nicht, aber das würde ja auch keinen Sinn machen, weil es in Python ausser ``global`` keine Deklarationen gibt.
Ich finde das Cairo-Beispiel übrigens nicht schön weil eine Klasse als Funktion missbraucht wird. So etwas versuche ich zumindest zu vermeiden.
Ich finde das Cairo-Beispiel übrigens nicht schön weil eine Klasse als Funktion missbraucht wird. So etwas versuche ich zumindest zu vermeiden.