Коришћење функције супер() у Питхон класама

Кључне Такеаваис

  • Питхон-ова функција супер() вам омогућава да позовете методе суперкласе из поткласе, што олакшава имплементацију наслеђивања и замене метода.
  • Функција супер() је уско повезана са редоследом решавања метода (МРО) у Питхон-у, који одређује редослед којим се класе претка траже за методе или атрибуте.
  • Коришћење супер() у конструкторима класа је уобичајена пракса за иницијализацију заједничких атрибута у родитељској класи и специфичнијих у подређеној класи. Неуспех коришћења супер() може довести до нежељених последица, као што је недостатак иницијализације атрибута.

Једна од кључних карактеристика Питхон-а је његова ООП парадигма, коју можете користити за моделирање стварних ентитета и њихових односа.

Када радите са Питхон класама, често ћете користити наслеђивање и заменити атрибуте или методе суперкласе. Питхон обезбеђује функцију супер() која вам омогућава да позовете методе суперкласе из поткласе.

Шта је супер() и зашто вам треба?

Користећи наслеђивање, можете направити нову Питхон класу која наслеђује карактеристике постојеће класе. Такође можете заменити методе суперкласе у поткласи, пружајући алтернативне имплементације. Међутим, можда бисте желели да користите нову функционалност поред старе, а не уместо ње. У овом случају, супер() је користан.

Можете користити функцију супер() за приступ атрибутима суперкласе и позивање метода суперкласе. Супер је од суштинског значаја за објектно оријентисано програмирање јер олакшава имплементацију наслеђивања и замене метода.

Како функционише супер()?

Интерно, супер() је блиско повезан са редоследом решавања метода (МРО) у Питхон-у, који одређује Ц3 алгоритам линеаризације.

Ево како супер() функционише:

  • Одредите тренутну класу и инстанцу: Када позовете супер() унутар методе поткласе, Питхон аутоматски открива тренутну класу (класу која садржи метод који је позвао супер()) и инстанцу те класе (тј. селф) .
  • Одредите суперкласу: супер() узима два аргумента — тренутну класу и инстанцу — које не морате експлицитно да проследите. Користи ове информације да одреди суперкласу за делегирање позива методе. То ради испитивањем хијерархије класа и МРО.
  • Позовите метод у Суперкласи: Када се одреди суперкласа, супер() вам омогућава да позовете њене методе као да их позивате директно из поткласе. Ово вам омогућава да проширите или заобиђете методе док још увек користите оригиналну имплементацију из суперкласе.
  • Коришћење супер() у конструктору класа

    Коришћење супер() у конструктору класе је уобичајена пракса, пошто ћете често желети да иницијализујете уобичајене атрибуте у родитељској класи и специфичније у детету.

    Да бисте ово демонстрирали, дефинишите Питхон класу, Фатхер, коју класа Сон наслеђује од:

     class Father:
        def __init__(self, first_name, last_name):
            self.first_name = first_name
            self.last_name = last_name

    class Son(Father):
        def __init__(self, first_name, last_name, age, hobby):
            
            super().__init__(first_name, last_name)

            self.age = age
            self.hobby = hobby

        def get_info(self):
            return f"Son's Name: {self.first_name} {self.last_name}, \
    Son's Age: {self.age}, Son's Hobby: {self.hobby}"


    son = Son("Pius", "Effiong", 25, "Playing Guitar")


    print(son.get_info())

    Унутар конструктора Сон, позив супер().инит() позива конструктор класе Фатхер, прослеђујући му име и презиме као параметре. Ово осигурава да класа Фатхер и даље може исправно поставити атрибуте имена, чак и на објекту Сон.

    Ако не позовете супер() у конструктору класе, конструктор његове надређене класе се неће покренути. Ово може довести до нежељених последица, као што су недостајуће иницијализације атрибута или непотпуно подешавање стања родитељске класе:

     ...
    class Son(Father):
        def __init__(self, first_name, last_name, age, hobby):
            self.age = age
            self.hobby = hobby
    ...

    Ако сада покушате да позовете метод гет_инфо, он ће покренути АттрибутеЕррор јер атрибути селф.фирст_наме и селф.ласт_наме нису иницијализовани.

    Коришћење супер() у методама класе

    Можете користити супер() у другим методама, осим у конструкторима, на исти начин. Ово вам омогућава да проширите или поништите понашање метода суперкласе.

     class Father:
        def speak(self):
            return "Hello from Father"

    class Son(Father):
        def speak(self):
            
            parent_greeting = super().speak()
            return f"Hello from Son\n{parent_greeting}"


    son = Son()


    son_greeting = son.speak()

    print(son_greeting)

    Класа Син наслеђује од Оца и има свој метод говора. Метод говора класе Сон користи супер().спеак() да позове метод говора класе Фатхер. Ово му омогућава да укључи поруку из надређене класе док је проширује поруком специфичном за подређену класу.

    Неуспех коришћења супер() у методи која замењује другу значи да функционалност присутна у методу родитељске класе неће ступити на снагу. Ово резултира потпуном заменом понашања методе, што може довести до понашања које нисте намеравали.

    Разумевање редоследа решавања метода

    Редослед решавања метода (МРО) је редослед којим Питхон претражује класе предака када приступате методу или атрибуту. МРО помаже Питхон-у да одреди који метод да позове када постоји више хијерархија наслеђивања.

     class Nigeria():
        def culture(self):
            print("Nigeria's culture")

    class Africa():
       def culture(self):
           print("Africa's culture")

    Ево шта се дешава када креирате инстанцу класе Лагос и позовете метод културе:

  • Питхон почиње тражењем методе културе у самој класи Лагос. Ако га пронађе, позива метод. Ако не, прелази се на други корак.
  • Ако не пронађе метод културе у класи Лагос, Питхон гледа основне класе редоследом којим се појављују у дефиницији класе. У овом случају, Лагос наслеђује прво из Африке, а затим из Нигерије. Дакле, Питхон ће прво потражити метод културе у Африци.
  • Ако не пронађе метод културе у класи Африка, Питхон ће онда потражити у класи Нигериа. Ово понашање се наставља све док не дође до краја хијерархије и доведе до грешке ако не може да пронађе метод у било којој од суперкласа.
  • Излаз приказује редослед Резолуције метода у Лагосу, почевши са лева на десно.

    Уобичајене замке и најбоље праксе

    Када радите са супер(), постоје неке уобичајене замке које треба избегавати.

  • Имајте на уму редослед решавања метода, посебно у сценаријима вишеструког наслеђивања. Ако треба да користите сложено вишеструко наслеђивање, требало би да сте упознати са Ц3 Алгоритам линеаризације које Питхон користи за одређивање МРО.
  • Избегавајте кружне зависности у хијерархији класа, што може довести до непредвидивог понашања.
  • Документујте свој код јасно, посебно када користите супер() у сложеним хијерархијама класа, како бисте га учинили разумљивијим за друге програмере.
  • Користите супер() на прави начин

    Питхон-ова супер() функција је моћна функција када радите са наслеђивањем и заменом метода. Разумевање како супер() функционише и праћење најбољих пракси омогућиће вам да креирате код у својим Питхон пројектима који је лакши за одржавање и ефикаснији.