متد super در پایتون — به زبان ساده
مطالب زیادی در اینترنت وجود دارند که به توضیح متد super در پایتون میپردازند، اما شاید با مطالعه همه آنها همچنان ندانید که برای فراخوانی یک متد از یک کلاس خاص روی یک زنجیره وراثت باید چه خصوصیتی را به متد super() ارسال کنید. به همین دلیل توصیه میکنیم این مقاله را تا انتها بخوانید تا به صورت عمیقتری با این متد پایتون آشنا شوید.
تصور کنید یک توسعهدهنده پایتون هستید و میخواهید کلاسی به نام PIDLimitedIntegral بنویسید که از PIDLimitedMV ارثبری میکند زیرا به برخی خصوصیتهای PIDLimitedMV نیاز دارد. PIDLimitedMV نیز از PID ارثبری میکند.
بدین ترتیب برای پیادهسازی صحیح متد ()calculate روی کلاس PIDLimitedIntegral میتوانیم از ()calculate روی PIDLimitedMV استفاده کنیم. بنابراین میتوانیم متد والد مستقیم PIDLimitedIntegral را overload کنیم. اما از سوی دیگر میتوانیم متد ()calculate را از کلاس PID نیز overload کنیم تا از اجبار به overload کامل متد خودداری کنیم. از این رو اگر میخواهیم متد صحیح را overload کنیم، نمیتوانیم از ()super بدون ارسال خصوصیتهای صحیح استفاده کنیم.
مثال
درخت وراثت زیر را در نظر بگیرید:
اکنون میخواهیم کدهای مربوطه را بنویسیم.
کد کلاس A ،B و C به صورت زیر است:
1class A:
2 def __init__(self):
3 print("A initiated")
4
5class B(A):
6 def __init__(self):
7 super().__init__()
8 print("B initiated")
9
10class C(B):
11 def __init__(self):
12 super(C, self).__init__()
13 print("C initiated")
اکنون تصور کنید بخواهیم کلاس c2 از متد ()__init__ مربوط به B عبور کند؛ اما متد ()__init__ مربوطه به A را اجرا کند. به بیان دیگر، می خواهیم متد ()__init__ از A به جای B ارث بری کند، هر چند والد مستقیم کلاس ما B است. این جایی است که کلاس C2 وارد بازی می شود. پیاه سازی آن چنین است:
1class C2(B):
2 def __init__(self):
3 super(B, self).__init__()
4 print("other C initiated")
چنان که از روی کد فوق مشخص است، همه کلاسها متد ()__init__ والد مستقیمشان را overload میکنند. از این رو برای استفاده از ()super بدون هیچ خصوصیتی کفایت میکند. بنابراین اگر دستور ()c = C، خروجی زیر را به دست میآوریم:
A initiated B initiated C initiated
در واقع ما به صورت مؤثری از ()__init__ والد مستقیم پرش کردهایم و به جای آن صرفاً متد ()__init__ مربوط به A فراخوانی شده است.
سخن پایانی درباره متد Super در پایتون
همچنان که در مستندات رسمی (+) میبینیم، متد ()super میتواند دو خصوصیت بگیرد. خصوصیت اول ارجاع کلاس است و دومی باید در صورتی استفاده شود که بخواهیم در زمان فراخوانی شدن متد ()super اتصالی داشته باشیم.
نکتهای که به طور خاص در این راهنما آموختیم این است که آن ارجاع کلاس که باید به متد ()super ارسال کنیم دقیقاً آن کلاسی که میخواهیم استفاده کنیم نیست، بلکه به جای آن از فرزند مستقیم آن را استفاده میکنیم. همان طور که در مثال فوق دیدیم میخواهیم متد ()__init__ مربوط به A را مورد استفاده قرار دهیم و از این رو باید B را به عنوان یک مرجع به متد ()super به صورت super(B, self) ارسال کنیم. این وضعیت کمی سردرگمکننده به نظر میرسد، اما راه درست آن چنین است.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای پایتون
- گنجینه آموزشهای برنامه نویسی پایتون (Python)
- مجموعه آموزشهای برنامهنویسی
- زبان برنامه نویسی پایتون (Python) — از صفر تا صد
- ترفندهای برنامه نویسی در پایتون — از صفر تا صد
==
با سلام و خسته نباشید
در واقع` super(B, self)` میشه یه نمونه از والد B(که اگه B از جایی ارث بری نکرده باشه مثل اینه از خودش ارث برده باشه) . درسته ؟
فقط چیزی که مبهم هست برام کاربرد self هست میشه یه راهنمایی کنید . ممنون