Dědičnost je užitečná, ale její plný potenciál můžete odemknout opětovným použitím kódu ze základních tříd.

Klíčové věci

  • Funkce super() Pythonu vám umožňuje volat metody nadtřídy z podtřídy, což usnadňuje implementaci dědičnosti a přepisování metod.
  • Funkce super() úzce souvisí s Method Resolution Order (MRO) v Pythonu, který určuje pořadí, ve kterém jsou třídy předků prohledávány pro metody nebo atributy.
  • Použití super() v konstruktorech třídy je běžnou praxí k inicializaci běžných atributů v nadřazené třídě a specifičtějších v podřízené třídě. Nepoužití super() může vést k nezamýšleným následkům, jako je chybějící inicializace atributů.

Jednou ze základních funkcí Pythonu je jeho paradigma OOP, které můžete použít k modelování entit reálného světa a jejich vztahů.

Při práci s třídami Pythonu budete často používat dědičnost a přepisovat atributy nebo metody nadtřídy. Python poskytuje a super() funkce, která vám umožní volat metody nadtřídy z podtřídy.

Co je super() a proč to potřebujete?

instagram viewer

Pomocí dědičnosti můžete vytvořit novou třídu Pythonu, která zdědí vlastnosti existující třídy. Můžete také přepsat metody nadtřídy v podtřídě a poskytnout tak alternativní implementace. Možná však budete chtít používat novou funkci jako doplněk ke staré, nikoli místo ní. V tomto případě, super() je užitečné.

Můžete použít super() funkce pro přístup k atributům nadtřídy a vyvolání metod nadtřídy. Super je nezbytný pro objektově orientované programování protože to usnadňuje implementaci dědičnosti a přepisování metod.

Jak funguje super()?

Vnitřně, super() úzce souvisí s Metoda Pořadí rozlišení (MRO) v Pythonu, který určuje lineární algoritmus C3.

Zde je návod super() funguje:

  1. Určete aktuální třídu a instanci: Když zavoláte super() uvnitř metody podtřídy Python automaticky zjistí aktuální třídu (třídu obsahující metodu, která volala super()) a instance této třídy (tj. ).
  2. Určete nadtřídu: super() bere dva argumenty – aktuální třídu a instanci – které nemusíte explicitně předávat. Tyto informace používá k určení nadtřídy k delegování volání metody. Dělá to zkoumáním třídní hierarchie a MRO.
  3. Vyvolejte metodu na nadtřídě: Jakmile je určena supertřída, super() umožňuje volat jeho metody, jako byste je volali přímo z podtřídy. To vám umožňuje rozšířit nebo přepsat metody a přitom stále používat původní implementaci z nadtřídy.

Použití super() v konstruktoru třídy

Použitím super() v konstruktoru třídy je běžná praxe, protože často budete chtít inicializovat běžné atributy v nadřazené třídě a specifičtější v podřízené třídě.

Chcete-li to demonstrovat, definovat třídu Pythonu, Otec, která a Syn třída dědí od:

classFather:
def__init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name

classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
# Call the parent class constructor (Father)
super().__init__(first_name, last_name)

self.age = age
self.hobby = hobby

defget_info(self):
returnf"Son's Name: {self.first_name}{self.last_name}, \
Son's Age: {self.age}, Son's Hobby: {self.hobby}"

# Create an instance of the Son class
son = Son("Pius", "Effiong", 25, "Playing Guitar")

# Access attributes
print(son.get_info())

Uvnitř Syn konstruktor, volání super().init() se dovolává Otec konstruktor třídy, předá ji jméno a příjmení jako parametry. Tím je zajištěno, že Otec třída může stále správně nastavit atributy názvu, a to i na a Syn objekt.

Pokud nezavoláte super() v konstruktoru třídy se konstruktor jeho nadřazené třídy nespustí. To může vést k nezamýšleným následkům, jako jsou chybějící inicializace atributů nebo neúplné nastavení stavu nadřazené třídy:

...
classSon(Father):
def__init__(self, first_name, last_name, age, hobby):
self.age = age
self.hobby = hobby
...

Pokud se nyní pokusíte zavolat na získat informace způsob, zvýší to an AttributeError protože self.křestní_jméno a self.prijmeni atributy nebyly inicializovány.

Použití super() v Class Methods

Můžeš použít super() v jiných metodách, kromě konstruktorů, stejným způsobem. To vám umožní rozšířit nebo přepsat chování metody nadtřídy.

classFather:
defspeak(self):
return"Hello from Father"

classSon(Father):
defspeak(self):
# Call the parent class's speak method using super()
parent_greeting = super().speak()
returnf"Hello from Son\n{parent_greeting}"

# Create an instance of the Son class
son = Son()

# Call the speak method of the Son class
son_greeting = son.speak()

print(son_greeting)

The Syn třída dědí z Otec a má své mluvit metoda. The mluvit metoda Syn třída používá super().mluv() zavolat na mluvit metoda Otec třída. To mu umožňuje zahrnout zprávu z nadřazené třídy a zároveň ji rozšířit o zprávu specifickou pro podřízenou třídu.

Nepoužívá se super() v metodě, která přepíše jinou, znamená, že funkce přítomné v metodě nadřazené třídy se neprojeví. Výsledkem je úplné nahrazení chování metody, což může vést k chování, které jste nezamýšleli.

Pochopení příkazu k rozlišení metod

Method Resolution Order (MRO) je pořadí, ve kterém Python prohledává třídy předků, když přistupujete k metodě nebo atributu. MRO pomáhá Pythonu určit, kterou metodu volat, když existuje více hierarchií dědičnosti.

classNigeria():
defculture(self):
print("Nigeria's culture")

classAfrica():
defculture(self):
print("Africa's culture")

Zde je to, co se stane, když vytvoříte instanci souboru Lagos třídy a zavolejte kultura metoda:

  1. Python začíná hledáním kultura metoda v Lagos samotná třída. Pokud ji najde, zavolá metodu. Pokud ne, přejde se ke druhému kroku.
  2. Pokud nenajde kultura metoda v Lagos třídy, Python se dívá na základní třídy v pořadí, v jakém se objevují v definici třídy. V tomto případě, Lagos dědí nejprve od Afrika a pak od Nigérie. Takže Python bude hledat kultura metoda v Afrika První.
  3. Pokud nenajde kultura metoda v Afrika třídy, Python se pak podívá do Nigérie třída. Toto chování pokračuje, dokud nedosáhne konce hierarchie a vyvolá chybu, pokud nemůže najít metodu v žádné z nadtříd.

Výstup zobrazuje pořadí rozlišení metody Lagos, počínaje zleva doprava.

Běžná úskalí a osvědčené postupy

Při práci s super(), existuje několik běžných úskalí, kterým je třeba se vyhnout.

  1. Mějte na paměti pořadí řešení metod, zejména ve scénářích více dědičnosti. Pokud potřebujete použít komplexní vícenásobnou dědičnost, měli byste být obeznámeni s C3 Linearizační algoritmus které Python používá k určení MRO.
  2. Vyhněte se cyklickým závislostem v hierarchii tříd, které mohou vést k nepředvídatelnému chování.
  3. Jasně zdokumentujte svůj kód, zejména při používání super() ve složitých hierarchiích tříd, aby byly srozumitelnější pro ostatní vývojáře.

Použijte super() správným způsobem

Pythonův super() Funkce je výkonná funkce, když pracujete s dědičností a přepsáním metody. Pochopení jak super() funguje a dodržování osvědčených postupů vám umožní vytvořit lépe udržovatelný a efektivnější kód ve vašich projektech Pythonu.