[Python-de] super()?

Thomas Fanslau tfanslau at gmx.de
Wed Sep 4 18:29:14 EDT 2002


(Das folgende ist vielleicht lang, aber doch nicht unwichtig. Sollte ich 
recht haben, und Test zeigen mir, das ich nicht wirklich falsch liege, 
dann muss bei der geplanten Verwendung von super() JEDE Klasse, selbst 
wenn sie keine Basisklasse ausser 'object' hat, ein super()-Aufruf 
eingetragen werden UND jeder dieser Aufrufe muss zumindestens mit einem 
try-except geklammert werden. Oder ich lieg völlig daneben, was ich nie 
völlig ausschliesse.)

Ich habe mir die Mails durchgelesen, die Dokumentation gewälzt 
(inclusive PEP 253), noch in bisschen getestet und ganz langsam kommt 
Licht in die Sache. Oder auch nicht :-(

Warum 'self.__class__' eine Endlos-Schleife ergibt ist jetzt eigentlich 
auch klar(schliesslich ist self.__class__ immer 'D' ;-). Meine Dummmheit.

Aber immer noch: Christian schreibt

class R(object) :
      def save(self):
	 print "r",

class A(R):
      def save(self):
          super(A, self).save()
          print "a",

class B(R):
     def save(self):
         super(B, self).save()
         print "b",

class D(B, A):
     def save(self):
         super(D, self).save()
         print "d"

d = D()
d.save()

Und sieh an: Ein Aufruf ergibt "r a b d". Wie kann das aber sein?

Ein paar Änderungen (R wird entfernt, A und B sind jetzt von 'object' 
abgeleitet, die super()-Aufrufe sind entfernt)

class A(object):
      def save(self):
          print "a",

class B(object):
     def save(self):
         print "b",

class D(B, A):
     def save(self):
         super(D, self).save()
         print "d"

d = D()
d.save()

Und der Aufruf ergibt (anstatt "a b d" wie ich das erwartet habe) "b d".

Noch ein Schritt weiter, noch eine kleine Änderung (in B wird der 
super()-Aufruf wieder eingefügt):

class A(object):
      def save(self):
          print "a",

class B(object):
     def save(self):
         super(B, self).save()
         print "b",

class D(B, A):
     def save(self):
         super(D, self).save()
         print "d"

d = D()
d.save()

Und, tata, "a b d" OBWOHL B GAR KEINE BASISKLASSE HAT!!!!

Will ich aber

b = B()
b.save()

sagen, spring mir das System logischerweise an den Hals, den B hat gar 
keine Basisklasse. Hahaha...

Inzwischen glaube ich das in Wirklichkeit folgendes passiert:

Laut PEP 253 wird die Liste der Superklassen nur beim Anlegen der Klasse 
einmal ermittelt.

Der erste super()-Aufruf für eine Instanz (kenntlich daran, das bei dem 
die angegebene Klasse die Klasse von self ist, also 'self.__class__ == 
class') beginnt am Anfang dieser Liste, liefert die erste Klasse zurück 
und ruft dann yield auf.

Alle weiteren super()-Aufrufe ignorieren alle übergebenen Parameter und 
liefern einfach die nächste Klasse aus der Liste.

Ist dann zwar nett, aber nach dem ich in obigem Beispiel in 'b.save()' 
eine Exception bekomme, andererseits ohne das super() dort 'a' gar nicht 
gespeichert wird, ist da irgendwo murks drin.

--tf





More information about the Python-de mailing list