برنامه نویسی ۲۹۹۱ بازدید

مطالب زیادی در اینترنت وجود دارند که به توضیح متد super در پایتون می‌پردازند، اما شاید با مطالعه همه آن‌ها همچنان ندانید که برای فراخوانی یک متد از یک کلاس خاص روی یک زنجیره وراثت باید چه خصوصیتی را به متد super()‎ ارسال کنید. به همین دلیل توصیه می‌کنیم این مقاله را تا انتها بخوانید تا به صورت عمیق‌تری با این متد پایتون آشنا شوید.

تصور کنید یک توسعه‌دهنده پایتون هستید و می‌خواهید کلاسی به نام PIDLimitedIntegral بنویسید که از PIDLimitedMV ارث‌بری می‌کند زیرا به برخی خصوصیت‌های PIDLimitedMV نیاز دارد. PIDLimitedMV نیز از PID ارث‌بری می‌کند.

متد super در پایتون

بدین ترتیب برای پیاده‌سازی صحیح متد ()calculate روی کلاس PIDLimitedIntegral می‌توانیم از ()calculate روی PIDLimitedMV استفاده کنیم. بنابراین می‌توانیم متد والد مستقیم PIDLimitedIntegral را overload کنیم. اما از سوی دیگر می‌توانیم متد ()calculate را از کلاس PID نیز overload کنیم تا از اجبار به overload کامل متد خودداری کنیم. از این رو اگر می‌خواهیم متد صحیح را overload کنیم، نمی‌توانیم از ()super بدون ارسال خصوصیت‌های صحیح استفاده کنیم.

مثال

درخت وراثت زیر را در نظر بگیرید:

متد super در پایتون

کد کلاس A ،B و C به صورت زیر است:

class A:
    def __init__(self):
            print("A initiated")

class B(A):
    def __init__(self):
            super().__init__()
            print("B initiated")

class C(B):
    def __init__(self):
            super(C, self).__init__()
            print("C initiated")

اکنون تصور کنید بخواهیم کلاس c2 از متد ()__init__ مربوط به B عبور کند؛ اما متد ()__init__ مربوطه به A را اجرا کند. به بیان دیگر، می خواهیم متد ()__init__  از A به جای B ارث بری کند، هر چند والد مستقیم کلاس ما B است. این جایی است که کلاس C2 وارد بازی می شود. پیاه سازی آن چنین است:

class C2(B):
    def __init__(self):
            super(B, self).__init__()
            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) ارسال کنیم. این وضعیت کمی سردرگم‌کننده به نظر می‌رسد، اما راه درست آن چنین است.

اگر این مطلب برای شما مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

==

بر اساس رای ۸ نفر
آیا این مطلب برای شما مفید بود؟
شما قبلا رای داده‌اید!
اگر بازخوردی درباره این مطلب دارید یا پرسشی دارید که بدون پاسخ مانده است، آن را از طریق بخش نظرات مطرح کنید.

«میثم لطفی» در رشته‌های ریاضیات کاربردی و مهندسی کامپیوتر به تحصیل پرداخته و شیفته فناوری است. وی در حال حاضر علاوه بر پیگیری علاقه‌مندی‌هایش در رشته‌های برنامه‌نویسی، کپی‌رایتینگ و محتوای چندرسانه‌ای، در زمینه نگارش مقالاتی با محوریت نرم‌افزار با مجله فرادرس همکاری دارد.

یک نظر ثبت شده در “متد super در پایتون — به زبان ساده

  • با سلام و خسته نباشید
    در واقع` super(B, self)` میشه یه نمونه از والد B(که اگه B از جایی ارث بری نکرده باشه مثل اینه از خودش ارث برده باشه) . درسته ؟
    فقط چیزی که مبهم هست برام کاربرد self هست میشه یه راهنمایی کنید . ممنون

نظر شما چیست؟

نشانی ایمیل شما منتشر نخواهد شد.

مشاهده بیشتر