2011-06-09 11 views
6

Mam klasy:Wstawki, wielo-dziedziczenia, konstruktorzy i dane

class A(object): 
    def __init__(self, *args): 
     # impl 

również "wstawek", w zasadzie inna klasa z niektórych danych i metody:

class Mixin(object): 
    def __init__(self): 
     self.data = [] 

    def a_method(self): 
     # do something 

Teraz tworzę podklasa A z mixin:

class AWithMixin(A, Mixin): 
    pass 

Mój problem polega na tym, że chcę, aby wywoływali konstruktorzy A i Mixin. Rozważałem nadanie AWithMixin własnego konstruktora, w którym super został wywołany, ale konstruktorzy super klas mają różne listy argumentów. Jaka jest najlepsza rozdzielczość?

+1

Co powstrzyma cię od wywołania konstruktorów dwóch klas bazowych (z odpowiednimi guments) z 'AWithMixin .__ init__'? – NPE

+0

To już zostało szczegółowo wyjaśnione. Zobacz http://stackoverflow.com/a/6100595/763269 –

Odpowiedz

8

Jestem dość nowy OOP też, ale to, co jest problemem w tym kodzie:

class AWithMixin(A, Mixin): 
    def __init__(self, *args): 
     A.__init__(self, *args) 
     Mixin.__init__(self) 
+2

to najlepsze rozwiązanie i zawsze go używam. Jednakże, jeśli zarówno 'A' jak i' Mixin' rozszerzają pewną klasę (np. 'Base') i oba wywołują' Base .__ init __() 'może być obowiązkowe użycie funkcji [super()] (http: // stackoverflow. com/q/576169). To skomplikowane IMHO i polecam znać, ale w miarę możliwości go unikać. – brandizzi

+0

@brandizzi, jak powiedziałem w odpowiedzi, jestem nowy w OOP. Wyglądałem na super funkcję, ale nie rozumiałem. Jeśli powiedziałem na tej klasie [super] kodu (AWithMixin, self) .__ init __() [/ code], jak mogę zadzwonić do A .__ init__ i Mixin .__ init__ zarówno? I podać różne argumenty? – utdemir

+1

Problem polega na tym, że to rozwiązanie nie jest szczególnie rozszerzalne i całkowicie ignoruje punkt enkapsulacji i określa mixin w niewłaściwej kolejności. Jeśli chcesz zastąpić metody w mixinie, to ten mixin przejmie kontrolę nad tą metodą i powinien być odpowiedzialny za wywoływanie tej samej metody w super klasie. Fakt, że mixin przyjmuje inną listę argumentów sugeruje, że została ona niepoprawnie zakodowana/nie została zaprojektowana do użytku z tą klasą potomną - narusza [LSP] (http://en.wikipedia.org/wiki/Liskov_substitution_principle)) . – quodlibetor

10
class A_1(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_1 constructor' 
     super(A_1, self).__init__(*args, **kwargs) 

class A_2(object): 
    def __init__(self, *args, **kwargs): 
     print 'A_2 constructor' 
     super(A_2, self).__init__(*args, **kwargs) 

class B(A_1, A_2): 
    def __init__(self, *args, **kwargs): 
     super(B, self).__init__(*args, **kwargs) 
     print 'B constructor' 

def main(): 
    b = B() 
    return 0 

if __name__ == '__main__': 
    main() 
  1. a_1 konstruktor
  2. konstruktor A_2
  3. konstruktor B
Powiązane problemy