Einige großartige Antworten hier, aber sie behandeln nicht die Frage, wie man super()
für den Fall, dass verschiedene Klassen in der Hierarchie unterschiedliche Signaturen haben ... insbesondere im Fall von __init__
diesen Teil zu beantworten und in der Lage zu sein, die super()
Ich würde vorschlagen, meine Antwort zu lesen. super() und Änderung der Signatur von kooperativen Methoden .
hier ist die Lösung für dieses Szenario:
- müssen die Klassen der obersten Ebene in Ihrer Hierarchie von einer benutzerdefinierten Klasse wie
SuperObject
:
- Wenn Klassen unterschiedliche Argumente annehmen können, übergeben Sie immer alle Argumente, die Sie erhalten haben, als Schlüsselwortargumente an die Superfunktion, und akzeptieren Sie immer
**kwargs
.
class SuperObject:
def __init__(self, **kwargs):
print('SuperObject')
mro = type(self).__mro__
assert mro[-1] is object
if mro[-2] is not SuperObject:
raise TypeError(
'all top-level classes in this hierarchy must inherit from SuperObject',
'the last class in the MRO should be SuperObject',
f'mro={[cls.__name__ for cls in mro]}'
)
# super().__init__ is guaranteed to be object.__init__
init = super().__init__
init()
Anwendungsbeispiel:
class A(SuperObject):
def __init__(self, **kwargs):
print("A")
super(A, self).__init__(**kwargs)
class B(SuperObject):
def __init__(self, **kwargs):
print("B")
super(B, self).__init__(**kwargs)
class C(A):
def __init__(self, age, **kwargs):
print("C",f"age={age}")
super(C, self).__init__(age=age, **kwargs)
class D(B):
def __init__(self, name, **kwargs):
print("D", f"name={name}")
super(D, self).__init__(name=name, **kwargs)
class E(C,D):
def __init__(self, name, age, *args, **kwargs):
print( "E", f"name={name}", f"age={age}")
super(E, self).__init__(name=name, age=age, *args, **kwargs)
E(name='python', age=28)
Ausgabe:
E name=python age=28
C age=28
A
D name=python
B
SuperObject