تابع ()Super در پایتون

استفاده از تابع داخلی ()super توی خیلی از پروژه ها و برنامه های شی گرا ضروریه و به maintain کردن پروژه کمک میکنه.

وقتی یک subclass یکی از متود های superclass رو بازنویسی یا override میکنه نیاز داریم که اون متود رو بدون اینکه هاردکد کنیم بنویسیم. روش توصیه شده اینکار به شکل زیر هستش:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Parent:  
    def __init__(self, txt):  
        self.message = txt  
  
    def printmessage(self):  
        print(self.message)  
  
class Child(Parent):  
    def __init__(self, txt):  
        super().__init__(txt)  
  
x = Child("Hello, and welcome!")
x.printmessage()

فراخوانی یک __init__ بازنویسی(override) شده توی استفاده اون ها در superclass ها اهمیت ویژه ای داره چون به اون ها اجازه میده تا وظیفه خودشون رو انجام بدن. مثل مثال بالا که توی کلاس child از ویژگی self.message برای پرینت پارامترمون استفاده میکنیم.

گاهی ممکنه کدی رو ببینیم که از این تابع استفاده نمیکنه، و مستقیما متد رو روی سوپرکلاس اجرا میکنه، مثل:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
class Parent:  
    def __init__(self, txt):  
        self.message = txt  
  
    def printmessage(self):  
        print(self.message)  
  
class Child(Parent):  
    def __init__(self, txt):  
        Parent.__init__(self, txt)  
  
x = Child("Hello, and welcome!")
x.printmessage()

در این مورد به خصوص، خروجی ما فرقی نکرد، اما به دو دلیل این روش توصیه نمیشه؛

اولین دلیل، هارد کد کردن کلاس بیسه. کلاس Parent ما هم تو تعریف کلاس استفاده شده و هم تو متد __init__ و خود همین موضوع در صورت تغییر کد و تغییر ندادن یکی از اون ها میتونه منجر به باگ بشه. اینکه با قانون DRY و ETC هم در تضاده یه دلیل دیگه مبنی بر اشباه بودن این کاره. دومین دلیل، خود تابع super() لاجیک هندل کردن سلسله مراتب کلاس ها با وراثت های چند گانه را پیاده سازی می کنه که بیشتر به وراثت مربوطه و تو یه پست دیگه اونو بررسی میکنیم.