قاعده ی mro

پرسیده شده
فعالیت 1264 روز پیش
دیده شده 793 بار
0

سلام

اگه یکی از کلاس ها از کلاس دیگه ای ارث بری کرده باشه؛ باید از  super برای init کردن method های parent استفاده کنیم؛

حالا چطوری از قاعده mro استفاده کنیم؟

تو فایل ضمیمه  کد و نمودار ساختار کلاس ها استفاده شده رو قرار دادم

 

فایل پیوست
realstate.zip
87.94 KB

هادی خانزاده
هادی خانزاده

19 آبان 99

0
حذف شده

سلااااااااااااااااام

ببین من جمله اولت رو یه مقدار تصحیح میکنم:

اگر یک کلاس از کلاس یا کلاس های دیگه ای ارث بری کرده باشه. میتونیم از super داخل متدهای کلاس فرزند استفاده کنیم تا متدهای کلاس پدر رو اجرا کنیم.

وقتی یه کلاس فرزند داریم که داره از کلاسی (که بهش میگیم کلاس پدر) ارث بری میکنه و کلاس پدر متد __init__ داره و حالا میخوایم تو کلاس فرزند متد __init__ رو بازنویسی (overwrite) کنیم، اکثرا لازم میشه که تو __init__ کلاس فرزند متد __init__ پدر یعنی super رو صدا بزنیم. یه تیکه کد برای مثال ببینیم که بهتر منظور این پاراگراف رو بفهمیم:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age


class Student(Person):
    def __init__(self, name, age, grade):
        super().__init__(name, age)
        self.grade = grade


s1 = Student("ali", "reza", 20)

 

قاعده MRO رو لازمه که بدونیم که وقتی داریم تو کلاس ها مون ارث بری انجام میدیم حواسمون باشه که چه اتفاقی داره می افته و method ها و attribute هارو تو کلاس های فرزند و پدر چطور بنویسیم. مخصوصا وقتی داریم Multiple Inheritance انجام میدیم.

 

حالا طبق این حرف ها و جلسه ی این تاپیک، بنظرم کدت باید اینطور اصلاح بشه:

class HouseInf:
    def __init__(self, age, area, rooms, address, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.age = age
        self.area = area
        self.rooms = rooms
        self.address = address


class Apartment(HouseInf):
    def __init__(self, floor, parking, elevator=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.parking = parking
        self.elevator = elevator
        self.floor = floor


class Sale:
    def __init__(self, price, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.price = price


class ApartmentSale(Apartment, Sale):
    def __str__(self):
        return f"{self.floor}, {self.age}"


if __name__ == '__main__':
    apartment_sale = ApartmentSale(floor=10, age=5, parking=1, elevator=True, rooms=3, address="tehran", area=120,
                                   price=500000)
    print(apartment_sale)

 

اگر باز سوالی داشتی یا نکته ای بود تو همین تاپیک بگو

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

20 آبان 99

0
حذف شده

سلام علیرضا خیلی ممنون از جواب کاملی که دادی با اینکه سوالم نامفهوم بود

مشکل من این بود که بعد از صدا زدن برای مقدار دهی؛ مقدار دهدی کلاس Apartment که تموم شد وارد کلاس Sale نمیشد

که کلید حل این مشکل super ای بود که به HouseInf اضافه شد درسته؟

که وقتی وارد HouseInf شد بعد از مقدار دهی متوجه بشه که init تموم نشد بره بعدی که بعدی میشه Sale

اما چرا توی کلاس Sale هم از super استفاده کردی؟

 

 

فایل پیوست

هادی خانزاده

توسط

هادی خانزاده

20 آبان 99

0
حذف شده

بله درسته.
من چند تا کار انجام دادم:

  1. توی همه __init__ های کلاس ها یه بار متد __init__ پدرشون یعنی super رو صدا زدم. و توی کلاس Sale صدا زدن __init__ پدرش super هیچ تاثیری نداره ولی یه convention و قرار داد هستش که بعضی از برنامه نویس های پایتون رعایت میکنن مثلا خود کلاس object که همه ی کلاس های پایتون ازش ارث بری میکنن هم این قرارداد رو رعایت کرده.
  2. ورودی های __init__ های کلاس هات رو یه مقدار قشنگ تر نوشتم.
  3. وقت ساخت ابجکت که از کللاس ApartmentSale استفاده کردی بهش price رو نداده بودی که من دادم.

برای فهمیدن تفاوت ۲ تا فایل هم میتونی از دستور diff یا git diff استفاده کنی که دقیقا بفهمی من چه تغییراتی تو کدت دادم. (در مورد این دستورات هم میتونی تو گوگل سرچ کنی)

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

20 آبان 99