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?
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:
- 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. já).
- 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.
- 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_nameclassSon(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 = hobbydefget_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:
- 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.
- 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í.
- 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.
- 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.
- Vyhněte se cyklickým závislostem v hierarchii tříd, které mohou vést k nepředvídatelnému chování.
- 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.