Python Academy · Oppitunti

Moniperintä ja MRO

Ymmärtäkää moniperintä ja Pythonin MRO (C3-linearisaatio).

Oppitunti 3/414 vaihetta

Moniperintä ja MRO on ilmainen Python Academy-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Python Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Python Academy-kurssilla on yhteensä 4 oppituntia.

Johdanto

Python tukee moniperintää. Metodinratkaisujärjestys (MRO) määrittää, mitä metodia kutsutaan, kun nimet ovat ristiriidassa.

Moniperinnän syntaksi

class C(A, B): perii sekä luokalta A että luokalta B. C saa kaikki metodit molemmilta.
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())

Metodinratkaisujärjestys (MRO)

MRO määrittää hakujärjestyksen. C.__mro__ näyttää järjestyksen: C, A, B, object. Ensimmäinen luokka, josta vastaava metodi löytyy, voittaa.
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__)

C3-linearisaatio

Python käyttää C3-linearisaatiota MRO:n laskemiseen. Se takaa, että aliluokka on ennen yliluokkaa ja että useat kantaluokat käsitellään vasemmalta oikealle.
class A: pass
class B(A): pass
class C(A): pass
class D(B, C): pass
print([c.__name__ for c in D.__mro__])

Timanttiperintä

D(B,C), jossa sekä B että C perivät A:n, muodostaa timanttiongelman. C3 takaa, että A:n __init__ kutsutaan vain kerran.
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()

Mixin-luokat

Mixin on moniperintää varten suunniteltu luokka. Se lisää metodeja toimimatta yksinään täydellisenä luokkana.
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())

Mixinien suunnittelusäännöt

Mixinien tulisi: olla sisältämättä __init__-metodia, olla perimättä muista kuin mixin-luokista ja tehdä yksi asia. Nimetkää ne Mixin-päätteellä.
class LoggingMixin:
    def log(self, msg): print(f'[{self.__class__.__name__}] {msg}')
class Service(LoggingMixin):
    def run(self): self.log('running')
Service().run()

super() moniperinnässä

super() kutsuu MRO:n seuraavaa luokkaa, joka ei välttämättä ole suora yliluokka. Jokaisen luokan on kutsuttava super()-metodia yhteistoiminnallisen toiminnan takaamiseksi.
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())

Dynaaminen luokan luominen type()-funktiolla

type('NewClass', (Base,), {'method': fn}) luo luokan dynaamisesti. Se on hyödyllinen metaprogrammoinnissa.
def hello(self): return 'hello'
MyClass = type('MyClass', (object,), {'hello': hello})
print(MyClass().hello())

MRO:n tarkistaminen

ClassName.__mro__ tai inspect.getmro(ClassName) näyttää metodinratkaisujärjestyksen luokkien muodostamana monikkona.
class A: pass
class B(A): pass
class C(B): pass
import inspect
print([c.__name__ for c in inspect.getmro(C)])

Milloin moniperintää kannattaa välttää

Monimutkaisia moniperintähierarkioita on vaikea hahmottaa. Suosikaa syvien hierarkioiden sijaan koostamista tai yksinkertaisia mixinejä.
# Prefer:
class User:
    def __init__(self, name, logger):
        self.name = name
        self.logger = logger  # composition
print('composition preferred')

Pikatarkistus

Mitä algoritmia Python käyttää metodinratkaisujärjestyksen laskemiseen?

Kertaus

Moniperintä: class C(A, B). MRO määräytyy C3-linearisoinnilla, joka määrittää metodien hakujärjestyksen. Käyttäkää siistiin moniperintään mixinejä. super() noudattaa MRO:ta.

Jatkakaa

Edistytte erinomaisesti! Jatkakaa, jotta hallitsette seuraavan käsitteen.
Aloita maksutta

Opi Python tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
76
Oppitunnit
320

Usein kysytyt kysymykset

Onko oppitunti ”Moniperintä ja MRO” ilmainen?

Kyllä – oppitunnin ”Moniperintä ja MRO” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Python Academy-kurssin, päivitä CoddyKit PROhon. Python Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Moniperintä ja MRO”?

Ymmärtäkää moniperintä ja Pythonin MRO (C3-linearisaatio). Harjoittelet Python Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Python Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Python Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Moniperintä ja MRO”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Python Academy-oppitunnilla?

Kyllä. Jokainen Python Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Yksittäinen periytyminen
  2. Metodien ylikirjoitus ja super()
  3. Moniperintä ja MRO
  4. Polymorfismi ja ankkatyypitys
← Takaisin: Python Academy