چرا super

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

سلام

 

 ۱- چرا ما داریم با super شی می سازیم super به ابجکت super اشاره می کنه و نمی تونیم از magic method ها استفاده کنیم و Exception Raise میکنه چرا من زمانی که از خود cls(*args **kwargs) می خوام ابجکت بسازم بازم Exception می دهد حتی با Singleton هم نمی تونم instance بسازم

 

 

فایل پیوست

mehrdad sarani1
mehrdad sarani1

6 آذر 99

2
حذف شده

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

 

جواب سوال ۱) وقتی ما از super(*args, **kwargs) داخل متد __new__ کلاس Singleton استفاده میکنیم (کدی که تو این جلسه داشتیم.) متدهای __new__ و __init__ کلاس پدرش رو صدا میزنیم و از اون متدها برای ساخت ابجکت استفاده میکنیم که کلاس پدر همه کلاس های پایتونی object هست. و اگر از cls(*args **kwargs) استفاده کنیم برای ساخت ابجکت در واقع داریم متدهای __new__ و __init__ کلاس Singleton رو صدا میزنیم که با اینکار داریم تو یه حلقه بینهایت می افتیم. چون وقتی cls(*args **kwargs) یا کلاس Singleton رو برای ساخت ابجکت صدا میزنیم. اول وارد متد __new__ کلاس Singleton میشه و دوباره به این خط cls(*args **kwargs) میخوره که باز میره سراغ متد __new__ کلاس Singleton و این یه حلقه بینهایت هست و پایتون بعد کلی تکرار جلوش رو میگیره.

 

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

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

6 آذر 99

0
حذف شده

بله خیلی ممنون مورد اول رو متوجه شدم توی یه loop میافته

ولی کلاس super یه آبجکت از super می سازه

که نمی شه به magic method ها دسترسی پیدا کرد بهت چرا نیست از static method استفاده کنیم و get instance رو انجام بدیم؟

فایل پیوست

mehrdad sarani1

توسط

mehrdad sarani1

6 آذر 99

0
حذف شده

نه این جمله ات درست نیست:

کلاس super یه آبجکت از super می سازه

ببین وقتی ما یه کلاس مثل Singleton رو صدا میزنم یه ابجکت ازش ساخته میشه و اون ابجکتی که ساخته رو برمیگردونه بهمون. در واقع وقتی یه کلاس مثل Singleton رو صدا میزنم:

Singleton(*argv, **kwargs)

1. میره دنبال تابع __new__ طبق MRO میگرده. بعد نتیجه کد زیر رو تو یه جایی ذخیره میکنه که ما اسمش رو tmp میذاریم فعلا:

Singleton.__new__(C, *argv, **kwargs)

2. بعد دنبال متد __init__ ابجکت tmp میگرده و نتیجه کد زیر رو به عنوان مقدار برگشتی از صدا زدن کلاس Singleton برمیگردونه:

self.__init__(*argv, **kwargs)

(نکته: اگر tmp ای که تو مرحله 1 ساخت type اش Singleton نباشه مرحله اصلا اجرا نمیشه.)

 

خب حالا برگردیم به اصل قضیه، وقتی ما super(*args, **kwargs) رو صدا میزنیم چه اتفاقی می افته؟

برای ساخت ابجکت از متد __new__ و متد __init__ کلاس پدرش استفاده میکنه برای ساخت ابجکت که تو این مثال کلاس پدر object هست. اما ابجکتی که برمیگرده type اش Singleton هست چون فقط از کدهای کلاس پدرش برای ساخت استفاده کرده.

 

این جمله رو هم نمیدونم طبق چی گفتی:

که نمی شه به magic method ها دسترسی پیدا کرد

چون میشه و دسترسی داریم مثلا کد زیر هیچ مشکلی نداره:

class Singleton:

    @classmethod
    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, 'instance'):
            cls.instance = super(*args, **kwargs)
        return cls.instance


s1 = Singleton()
print(s1.__class__)
print(s1.__hash__())
print(s1.__sizeof__())
print(s1.__str__())

 

مساله آخری که پرسیدی:

بهت چرا نیست از static method استفاده کنیم و get instance رو انجام بدیم؟

رو نمیدونم و از استاد رمضان پور میپرسم.

 

 

منابع:

https://jfine-python-classes.readthedocs.io/en/latest/call-a-class.html

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

6 آذر 99

1
حذف شده

این سوالت رو از استاد رمضان پور پرسیدم:

بهت چرا نیست از static method استفاده کنیم و get instance رو انجام بدیم؟

استاد برام یه ویس فرستادن. جواب استاد رمضان پور با یه کوچولو اصلاح این بود: 
«...این اشتباهی یه که تو یکی دیگه از سوالاتی که تو یه تاپیک دیگه مربوط به همین Singleton پرسیده شده بود وجود داره. یعنی هر 2 تا سوال این اشکال رو دارن. من نکته‌ام اینه که وقتی یه کلاسی Singleton میشه، هیچ ابجکت اضافی ای ازش ساخته نشه یعنی کلا در طول اجرای برنامه فقط یکبار، ابجکت از اون کلاس ساخته بشه. ولی سوالی که دوستان دارن میگن که خب چه اشکالی داره ما هر بار که صدا زده میشه یه ابجکت بسازیم ولی اون ابجکت اولی یه که ساختیم رو برگردونیم. یعنی اگر 10 بار صدا زده میشه. ما دفعه اول یه ابجکتی بسازیم یه جایی ذخیره کنیم. بار دوم یه ابجکت جدید بسازیم، اولی یه رو برگردونیم. بار سوم یه ابجکت جدید بسازیم اولی یه رو برگردونیم. خب این که خیلی کار عجیب غربیه که...
توی هر 2 تا سناریو، توی هر 2 تا سوال این اتفاق می افته. من توی ویدیو هم گفتم. گفتم رسیدن به init یعنی اینکه اون self ساخته شده و یه فضایی توی حافظه اشغال کرده و آدرسی تو حافظه داره. و گرنه این که خیلی ساده است که ما یه if میذاشتیم توی init و میگفتیم که اگر قبلا ساخته شده اون قبلی یه رو برگردون. ولی نکته این جاست که همین الان هم دوباره یه دونه جدید ساخته میشه و حالا ما فقط نهایتا ناقص ولش میکنیم یعنی مقدار دهیش نمیکنیم. و این اتفاقا یه آنتی پترنه توی Singleton یعنی خیلی نهی شده این کار توی تعاریف Singleton که آقا به هیچ وجه اینکارو نکنید! و یه جوری کلاس تون رو بنویسید که فقط یه نمونه ازش ساخته بشه...»

فایل پیوست

محمدعلی رضا

توسط

محمدعلی رضا

7 آذر 99