Vererbung: Attribute aus Subklassen in Basisklassen

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.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na du musst halt immer super aufrufen. Eigentlich in jeder Klasse. Weißt ja nicht, ob die mal abgelitten wird. Mache ich zugegeben aber auch nicht. Man muss es halt wissen.
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

Verstehe, ich glaube da muss ich erst noch ein Gefühl für bekommen. Um's mir heute nochmal richtig zu geben habe ich noch ein weiteres Beispiel bearbeitet, ich glaube jetzt habe ich mal ein Grundverständnis für den ganzen Zauber:

Code: Alles auswählen

class BaseClass:
    num_base_calls = 0

    def call_me(self):
        print(4)
        print("Calling method on Base Class")
        self.num_base_calls += 1


class LeftSubClass(BaseClass):
    num_left_sub_calls = 0

    def call_me(self):
        print(3)
        super().call_me()
        print("Calling method on Left Sub Class")
        self.num_left_sub_calls += 1


class RightSubClass(BaseClass):
    num_right_sub_calls = 0

    def call_me(self):
        print(2)
        super().call_me()
        print("Calling method on Right sub Class")
        self.num_right_sub_calls += 1


class SubClass(LeftSubClass, RightSubClass):
    num_sub_calls = 0

    def call_me(self):
        print(1)
        super().call_me()
        print("Calling method on Sub Class")
        self.num_sub_calls += 1


s = SubClass()
s.call_me()

print("base: ", s.num_base_calls)
print("left sub: ", s.num_left_sub_calls)
print("right sub: ", s.num_right_sub_calls)
print("sub: ", s.num_sub_calls)
Ausgabe:

1
3
2
4
Calling method on Base Class
Calling method on Right sub Class
Calling method on Left Sub Class
Calling method on Sub Class
base: 1
left sub: 1
right sub: 1
sub: 1

Jetzt weiß ich auch, warum mein ursprünglicher Ansatz via A.__init__(), B.__init__() in der __init__()-Methode von C potentiell in die Hose gehen könnte, bei obigen Beispiel fiel mir auf, dass dabei BaseClass doppelt aufgerufen wird. Jetzt werde ich von super() träumen %)
When we say computer, we mean the electronic computer.
Benutzeravatar
__blackjack__
User
Beiträge: 13079
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also ich finde super alles andere als super und in meinem Code habe ich einfach grundsätzlich keine Mehrfachvererbung ausser in seltenen Fällen Mixins wo das nicht nötig ist. Das macht mir nur Kopfschmerzen für etwas was ich noch nie gebraucht habe und auch nicht brauchen werde. Ich empfehle zu dem Thema diese Lektüre: Python's Super is nifty, but you can't use it.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
sls
User
Beiträge: 480
Registriert: Mittwoch 13. Mai 2015, 23:52
Wohnort: Country country = new Zealand();

@__blackjack__: ich muss gestehen dass mich super() ziemlich verunsichert. Laut dem von dir verlinkten Artikel soll man super() in Subklassen immer implementieren, wenn es denn die Basisklasse auch tut, ich hatte ja ein wenig die Hoffnung dass ich super() einfach meiden könnte, für das folgende Problem habe ich allerdings keine alternative, wenn `A` oder `B` super() implementiert:

Code: Alles auswählen

class A:
    def __init__(self, a1, a2, *args, **kwargs):
        print("A has been called.")
        super().__init__(*args, **kwargs)
        self.a1 = a1
        self.a2 = a2

class B:
    def __init__(self, b1, b2, *args, **kwargs):
        print("B has been called.")
        super().__init__(*args, **kwargs)
        self.b1 = b1
        self.b2 = b2


class C(A, B):
    def __init__(self, a1, a2, b1, b2, c1, c2, *args, **kwargs):
        super().__init__(a1, a2, b1, b2, *args, **kwargs)
        self.c1 = c1
        self.c2 = c2


c = C(1, 2, 3, 4, 5, 6)
print(c.a1, c.a2, c.b1, c.b2, c.c1, c.c2)
Gerade die ganzen Webframeworks mit denen ich öfter herummache nutzen munter super, teilweise ist die Beschreibung nicht ganz so toll, so dass ich bei Mehrfachvererbung teilweise Schwierigkeiten habe überhaupt zu erkennen *woher* welche Argumente kommen sollen.
When we say computer, we mean the electronic computer.
__deets__
User
Beiträge: 14529
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist in der Realität ein ziemliches nicht-Problem. Es zu verstehen hilft wenn man es mal braucht. Doch das ist selten. Wir sind ja nicht Java.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Es ist ein generelles Problem, dass Mehrfachvererbung mit unterschiedlichen __init__-Parametern ein unschönes Problem ist. Daher ist Mehrfachvererbung generell etwas, was man vermeiden möchte.
Antworten