اگه یکی از کلاسها از کلاس دیگه ای ارث بری کرده باشه؛ باید از super برای init کردن methodهای parent استفاده کنیم؛
حالا چطوری از قاعده mro استفاده کنیم؟
تو فایل ضمیمه کد و نمودار ساختار کلاسها استفاده شده رو قرار دادم
سلااااااااااااااااام
ببین من جمله اولت رو یه مقدار تصحیح میکنم:
اگر یک کلاس از کلاس یا کلاسهای دیگه ای ارث بری کرده باشه. میتونیم از 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)
اگر باز سوالی داشتی یا نکته ای بود تو همین تاپیک بگو
بهترین پاسخ
محمدعلی رضا۲۰ آبان ۱۳۹۹، ۰۵:۵۰
سلام علیرضا خیلی ممنون از جواب کاملی که دادی با اینکه سوالم نامفهوم بود
مشکل من این بود که بعد از صدا زدن برای مقدار دهی؛ مقدار دهدی کلاس Apartment که تموم شد وارد کلاس Sale نمیشد
که کلید حل این مشکل super ای بود که به HouseInf اضافه شد درسته؟
که وقتی وارد HouseInf شد بعد از مقدار دهی متوجه بشه که init تموم نشد بره بعدی که بعدی میشه Sale
اما چرا توی کلاس Sale هم از super استفاده کردی؟
هادی خانزاده۲۰ آبان ۱۳۹۹، ۰۷:۴۰
بله درسته. من چند تا کار انجام دادم:
توی همه __init__های کلاسها یه بار متد __init__ پدرشون یعنی super رو صدا زدم. و توی کلاس Sale صدا زدن __init__ پدرش super هیچ تاثیری نداره ولی یه convention و قرار داد هستش که بعضی از برنامه نویسهای پایتون رعایت میکنن مثلا خود کلاس object که همه ی کلاسهای پایتون ازش ارث بری میکنن هم این قرارداد رو رعایت کرده.
ورودیهای __init__های کلاس هات رو یه مقدار قشنگتر نوشتم.
وقت ساخت ابجکت که از کللاس ApartmentSale استفاده کردی بهش price رو نداده بودی که من دادم.
برای فهمیدن تفاوت ۲ تا فایل هم میتونی از دستور diff یا git diff استفاده کنی که دقیقا بفهمی من چه تغییراتی تو کدت دادم. (در مورد این دستورات هم میتونی تو گوگل سرچ کنی)