0Pricing
Python Academy · Lekcja

Dziedziczenie wielokrotne i MRO

Proszę zrozumieć dziedziczenie wielokrotne oraz MRO w Pythonie (linearyzację C3).

Dziedziczenie wielokrotne i MRO to bezpłatna lekcja Python Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Python Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Python Academy zawiera 4 lekcji w sumie.

Wprowadzenie

Python obsługuje wielokrotne dziedziczenie. Kolejność wyszukiwania metod (MRO) określa, która metoda zostanie wywołana, gdy nazwy się pokrywają.

Składnia wielokrotnego dziedziczenia

class C(A, B): dziedziczy zarówno po A, jak i po B. C otrzymuje wszystkie metody obu klas.
class A:
    def hello(self): return 'A'
class B:
    def world(self): return 'B'
class C(A, B): pass
c = C()
print(c.hello(), c.world())

Kolejność wyszukiwania metod (MRO)

MRO definiuje kolejność wyszukiwania. C.__mro__ pokazuje kolejność: C, A, B, object. Wygrywa pierwsza klasa zawierająca pasującą metodę.
class A:
    def greet(self): return 'A'
class B:
    def greet(self): return 'B'
class C(A, B): pass
print(C().greet())  # A wins
print(C.__mro__)

Linearyzacja C3

Python używa linearyzacji C3 do obliczania MRO. Gwarantuje ona, że klasa potomna występuje przed nadrzędną, a wiele klas bazowych jest uwzględnianych od lewej do prawej.
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print([c.__name__ for c in D.__mro__])

Dziedziczenie diamentowe

D(B,C), gdzie B i C dziedziczą po A, to problem diamentu. C3 zapewnia, że __init__ klasy A zostanie wywołana tylko raz.
class A:
    def __init__(self): print('A')
class B(A):
    def __init__(self): super().__init__(); print('B')
class C(A):
    def __init__(self): super().__init__(); print('C')
class D(B, C):
    def __init__(self): super().__init__(); print('D')
D()

Domieszki (mixiny)

Mixin to klasa zaprojektowana do wielokrotnego dziedziczenia. Dodaje metody, ale nie funkcjonuje samodzielnie jako pełna klasa.
class JSONMixin:
    def to_json(self):
        import json
        return json.dumps(vars(self))
class User(JSONMixin):
    def __init__(self, name, age): self.name,self.age=name,age
print(User('Alice', 30).to_json())

Zasady projektowania mixinów

Mixiny powinny: nie mieć __init__, nie dziedziczyć po klasach, które nie są mixinami, oraz realizować jedno zadanie. Ich nazwy powinny kończyć się przyrostkiem Mixin.
class LoggingMixin:
    def log(self, msg): print(f'[{self.__class__.__name__}] {msg}')
class Service(LoggingMixin):
    def run(self): self.log('running')
Service().run()

super() w wielokrotnym dziedziczeniu

super() wywołuje następną klasę w MRO, a niekoniecznie bezpośrednią klasę nadrzędną. Każda klasa musi wywoływać super(), aby zapewnić kooperatywne działanie.
class Base:
    def action(self): return 'Base'
class A(Base):
    def action(self): return 'A->' + super().action()
class B(Base):
    def action(self): return 'B->' + super().action()
class C(A, B):
    def action(self): return 'C->' + super().action()
print(C().action())

type() do dynamicznego tworzenia klas

type('NewClass', (Base,), {'method': fn}) tworzy klasę dynamicznie. Jest to przydatne w metaprogramowaniu.
def hello(self): return 'hello'
MyClass = type('MyClass', (object,), {'hello': hello})
print(MyClass().hello())

Sprawdzanie MRO

ClassName.__mro__ lub inspect.getmro(ClassName) pokazuje kolejność wyszukiwania jako krotkę klas.
class A: pass
class B(A): pass
class C(B): pass
import inspect
print([c.__name__ for c in inspect.getmro(C)])

Kiedy unikać wielokrotnego dziedziczenia

Złożone hierarchie wielokrotnego dziedziczenia są trudne do przeanalizowania. Zamiast głębokich hierarchii lepiej używać kompozycji lub prostych mixinów.
# Prefer:
class User:
    def __init__(self, name, logger):
        self.name = name
        self.logger = logger  # composition
print('composition preferred')

Szybkie sprawdzenie

Jakiego algorytmu używa Python do obliczania kolejności rozwiązywania metod (MRO)?

Podsumowanie

Wielokrotne dziedziczenie: class C(A, B). MRO wyznaczane za pomocą linearyzacji C3 określa kolejność wyszukiwania metod. Miksy (mixins) pomagają tworzyć przejrzyste hierarchie wielokrotnego dziedziczenia. super() podąża za MRO.

Proszę kontynuować

Doskonale Państwu idzie! Proszę kontynuować naukę, aby opanować kolejne zagadnienie.

Często zadawane pytania

Czy lekcja „Dziedziczenie wielokrotne i MRO” jest bezpłatna?

Tak — pełny tekst „Dziedziczenie wielokrotne i MRO” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Python Academy, przejdź na CoddyKit PRO. Kurs Python Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Dziedziczenie wielokrotne i MRO”?

Proszę zrozumieć dziedziczenie wielokrotne oraz MRO w Pythonie (linearyzację C3). Ćwiczysz Python Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Python Academy?

Nie wymagamy żadnego doświadczenia. Python Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.

Ile czasu zajmuje lekcja „Dziedziczenie wielokrotne i MRO”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Python Academy?

Tak. Każda lekcja Python Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Dziedziczenie pojedyncze
  2. Przesłanianie metod i super()
  3. Dziedziczenie wielokrotne i MRO
  4. Polimorfizm i kaczego typowanie
← Powrót do Python Academy