Seite 1 von 1
Vererbung
Verfasst: Freitag 25. Dezember 2009, 16:01
von kostonstyle
Hallo habe eine Frage zu der Vererbung, dieser Code hier
Code: Alles auswählen
class DahlManager(models.Manager):
def get_query_set(self):
return super(DahlManager, self).get_query_set().filter(author='Roald Dahl')
Die Klasse DahlManager erbt von der Klasse Manager. Der Aufruf von Basisklasse super(DahlManager, ..... das hängt bei mir. Wenn ich die Definition von Manager anschaue
Code: Alles auswählen
class Manager(object):
# Tracks each time a Manager instance is created. Used to retain order.
creation_counter = 0
def __init__(self):
super(Manager, self).__init__()
self._set_creation_counter()
self.model = None
self._inherited = False
hier wird wieder der constructor von der basisklasse aufgerufen, aber warum wird hier das Manager Objekt übergeben?
Vielen Dank kostonstyle
Verfasst: Freitag 25. Dezember 2009, 20:54
von cofi
Die Syntax von `super` ist folgende:
``super(ClassObject, InstanceObject).supers_function()``
ClassObject ist das Objekt, dessen Basisklasse du ansprechen willst; InstanceObject ist das Objekt, das als Exemplar uebergeben wird (Es wird kein neues erzeugt! Z.B. arbeitet ``__init__`` im Manager-Code auf dem Manager-Exemplar, nicht auf dem object-Exemplar).
Verfasst: Sonntag 27. Dezember 2009, 17:39
von kostonstyle
bei diesem beispiel, heisst das, dass der Befehl super das Objekt Manager aufruft, sich selber? Ist das ein rekursiver Aufruf?
Was bewirkt den so ein Befehl, bitte ein konkretes Beispiel!
Danke kostonstyle
Verfasst: Sonntag 27. Dezember 2009, 18:04
von Darii
Nein, super ermittelt eine Superklasse von Manager und leitet die Methodenaufrufe weiter. Das ganze sieht nur so merkwürdig aus, da Python dynamisch ist und zudem Mehrfachvererbung unterstützt. Im Endeffekt stellt super sicher, dass jede Methode nur einmal aufgerufen wird. Am besten nimmst du es erstmal so hin, dass man das so schreiben muss.
PS: super ist eine Funktion kein Befehl.
Verfasst: Sonntag 27. Dezember 2009, 18:48
von HWK
Vielleicht wird es verständlicher, wenn man super mit dem ähnlichen, wenn auch nicht identischen Aufruf
vergleicht?
MfG
HWK
Verfasst: Sonntag 27. Dezember 2009, 19:50
von kostonstyle
um alles zu verdeutlichen habe ich mir ein Beispiel programmiert
Code: Alles auswählen
class basis(object):
def __init__(self):
print("Basisklasse")
class sub(basis):
def __init__(self):
super(sub, self).__init__()
print("Subklasse")
a = sub()
die Ausgabe
warum muss ich hier in der funktion die sub klasse angeben und auch self? Es würde viel logischer, anstatt sub, basis anzugeben, wegen die Mehrfachvererbung, damit der Compiler weiss, welche Basisklasse gemeint ist.
ein zweiter Versuch
Code: Alles auswählen
class basis(object):
def __init__(self):
print("Basisklasse")
class sub(basis):
def __init__(self):
super(basis, self).__init__()
print("Subklasse")
a = sub()
die ausgabe
die ausgabe ist nur subklasse..ahhh ist logisch, der compiler sucht ja nach der superklasse von basis.
noch ein dritter versucht
Code: Alles auswählen
class basis(object):
def __init__(self):
print("Basisklasse")
class sub(basis):
def __init__(self):
super.__init__()
print("Subklasse")
a = sub()
warum erscheint eine fehlermeldung
Code: Alles auswählen
TypeError: descriptor '__init__' of 'super' object needs an argument
File "/Volumes/Develop/excourse.py", line 10, in <module>
a = sub()
File "/Volumes/Develop/excourse.py", line 7, in __init__
super.__init__()
Verfasst: Sonntag 27. Dezember 2009, 20:01
von cofi
kostonstyle hat geschrieben:warum muss ich hier in der funktion die sub klasse angeben und auch self? Es würde viel logischer, anstatt sub, basis anzugeben, wegen die Mehrfachvererbung, damit der Compiler weiss, welche Basisklasse gemeint ist.
Du hast `super` noch nicht verstanden. `super` sucht nach nach der Basisklasse anhand des Klassenobjekts und des Exemplars. Wuerdest du die Basisklasse angeben, waere `super` ueberfluessig und du koenntest das direkt aufrufen. Nebenbei weiss der Interpreter viel besser wie die Interna aussehen und wie er effizient als du.
kostonstyle hat geschrieben:
warum erscheint eine fehlermeldung
Weil `super` immernoch eine Funktion ist (anders als in Java, falls du von dort kommst)
Verfasst: Sonntag 27. Dezember 2009, 20:34
von kostonstyle
so könnte eine Vererbung aufbauen
Code: Alles auswählen
class Base():
def __init__(self, param):
print "Base:", param
def method(self, param):
print "Base.method:", param
class Derived(Base):
def __init__(self, param):
Base.__init__(self, param)
print "Derived:", param
def method(self, param):
Base.method(self, param)
print "Derived.method:", param
d = Derived("me")
Hier wird basisklasse eindeutig aufgerufen.
Warum ist bei der super Funktion das Klassenobjekt sich selber(also z.B sub anstatt basis) und was ist überhaupt Examplar. Da Python die Mehrfachvererbung unterstützt, wie weiss die super Funktion, welche basisklasse er nehmen sollte?
Ich komme aus der ABAP Welt
Danke kostonstyle
Verfasst: Sonntag 27. Dezember 2009, 21:05
von Darii
kostonstyle hat geschrieben:warum muss ich hier in der funktion die sub klasse angeben und auch self? Es würde viel logischer, anstatt sub, basis anzugeben, wegen die Mehrfachvererbung, damit der Compiler weiss, welche Basisklasse gemeint ist.
Nein, weil die Basisklassen deiner Klasse gesucht werden und nicht eine spezielle Klasse. Außerdem hast du vergessen bei deiner Basisklasse auch super() aufzurufen.
Verfasst: Sonntag 27. Dezember 2009, 21:41
von cofi
kostonstyle hat geschrieben:Da Python die Mehrfachvererbung unterstützt, wie weiss die super Funktion, welche basisklasse er nehmen sollte?
Wegen der MRO, viel spass beim durchkaempfen:
http://www.python.org/download/releases/2.3/mro/