بيثون: استخدم دائمًا __new__ بدلاً من __init__؟
-
01-10-2019 - |
سؤال
أنا أفهم كيف كلاهما __init__
و __new__
الشغل. أنا أتساءل عما إذا كان هناك أي شيء __init__
تستطيع أن تفعل ذلك __new__
لا تستطيع؟
أي يمكن استخدام __init__
يتم استبداله بالنمط التالي:
class MySubclass(object):
def __new__(cls, *args, **kwargs):
self = super(MySubclass, cls).__new__(cls, *args, **kwargs)
// Do __init__ stuff here
return self
أنا أسأل لأنني أرغب في جعل هذا الجانب من Python oo يتناسب بشكل أفضل في رأسي.
المحلول 2
إجابة واحدة محتملة من وظيفة Guido (شكرًا @fraca7):
على سبيل المثال ، في وحدة المخلل ،
__new__
يستخدم لإنشاء مثيلات عندما لا تنطوي على الكائنات. في هذه الحالة ، يتم إنشاء مثيلات ، ولكن__init__
الطريقة لم يتم الاحتجاج بها.
أي إجابات مماثلة أخرى؟
أنا أقبل هذه الإجابة على أنها "نعم" لسؤالي الخاص:
أنا أتساءل عما إذا كان هناك أي شيء
__init__
تستطيع أن تفعل ذلك__new__
لا تستطيع؟
نعم ، على عكس __new__
, ، الإجراءات التي تضعها في __init__
لن يتم تنفيذ الطريقة أثناء عملية إلغاء الاختيار. __new__
لا يمكن أن تجعل هذا التمييز.
نصائح أخرى
لذلك ، فئة الفصل عادة type
, ، وعندما تتصل Class()
ال __call__()
طريقة على Class
الفصل يتعامل مع ذلك. أعتقد type.__call__()
يتم تنفيذها أكثر أو أقل مثل هذا:
def __call__(cls, *args, **kwargs):
# should do the same thing as type.__call__
obj = cls.__new__(cls, *args, **kwargs)
if isinstance(obj, cls):
obj.__init__(*args, **kwargs)
return obj
الإجابة المباشرة على سؤالك هي لا ، الأشياء التي __init__()
يمكن القيام (تغيير / "تهيئة" مثيل محدد) هو مجموعة فرعية من الأشياء التي __new__()
يمكن القيام بذلك (إنشاء أو حدد أي كائن يريده ، فعل أي شيء لهذا الكائن الذي يريده قبل إرجاع الكائن).
من المريح أن يكون لديك كلتا الطريقتين للاستخدام. استخدام __init__()
هو أبسط (ليس من الضروري إنشاء أي شيء ، وليس من الضروري إعادة أي شيء) ، وأعتقد أنه من الأفضل استخدام الممارسات دائمًا __init__()
ما لم يكن لديك سبب محدد للاستخدام __new__()
.
حسنا ، تبحث عن __new__ vs __init__
أظهر لي Google هذه.
قصة طويلة قصيرة، __new__
إرجاع مثيل كائن جديد ، بينما __init__
لا يعيد أي شيء وتهيئة أعضاء الفصل.
تحرير: للإجابة على سؤالك فعليًا ، يجب ألا تحتاج أبدًا إلى تجاوز __new__
ما لم تكن أنواعًا غير قابلة للتغيير.