नया जादू super()
व्यवहार DRY (अपने आप को दोहराएं नहीं) सिद्धांत का उल्लंघन करने से बचने के लिए जोड़ा गया था, PEP 3135 देखें । स्पष्ट रूप से एक वैश्विक के रूप में संदर्भित करके कक्षा का नाम रखने के साथ ही उन विद्रोही मुद्दों का भी खतरा है जिन्हें आपने super()
स्वयं खोजा था:
class Foo(Bar):
def baz(self):
return super(Foo, self).baz() + 42
Spam = Foo
Foo = something_else()
Spam().baz() # liable to blow up
यही बात क्लास डेकोरेटर्स का उपयोग करने पर लागू होती है जहाँ डेकोरेटर एक नई वस्तु देता है, जो क्लास के नाम को रीबाइंड करता है:
@class_decorator_returning_new_class
class Foo(Bar):
def baz(self):
# Now `Foo` is a *different class*
return super(Foo, self).baz() + 42
मैजिक super()
__class__
सेल आपको मूल वर्ग ऑब्जेक्ट तक पहुंच प्रदान करके इन मुद्दों को अच्छी तरह से दरकिनार कर देता है।
पीईपी को गुइडो द्वारा मार दिया गया था, जिसने शुरू में super
एक कीवर्ड बनने की कल्पना की थी , और वर्तमान वर्ग को देखने के लिए एक सेल का उपयोग करने का विचार भी उसका था । निश्चित रूप से, इसे एक कीवर्ड बनाने का विचार पीईपी के पहले मसौदे का हिस्सा था ।
हालाँकि, यह वास्तव में स्वयं Guido था, जिसने इसके बाद वर्तमान कार्यान्वयन का प्रस्ताव करते हुए कीवर्ड आइडिया को 'बहुत जादुई' के रूप में छोड़ दिया। उन्होंने अनुमान लगाया कि एक अलग नाम का उपयोग करने से super()
समस्या हो सकती है :
मेरा पैच एक मध्यवर्ती समाधान का उपयोग करता है: यह मानता है कि __class__
जब भी आप एक चर नाम का उपयोग करते हैं, तो आपको इसकी आवश्यकता होती है 'super'
। इस प्रकार, यदि आप (विश्व स्तर पर) का नाम बदलने super
के लिए supper
और उपयोग supper
नहीं बल्कि super
, यह तर्क बिना काम नहीं करेगा (लेकिन यह अभी भी काम करता है, तो आप इसे पारित या तो
__class__
या वास्तविक वर्ग वस्तु); यदि आपके पास नाम का एक असंबंधित चर है super
, तो चीजें काम करेंगी लेकिन विधि सेल चर के लिए उपयोग किए जाने वाले थोड़ा धीमा कॉल पथ का उपयोग करेगी।
तो, अंत में, यह स्वयं Guido था जिसने घोषणा की कि एक super
कीवर्ड का उपयोग करना सही नहीं लगा, और यह कि एक जादू __class__
सेल प्रदान करना एक स्वीकार्य समझौता था।
मैं मानता हूं कि कार्यान्वयन का जादू, निहित व्यवहार कुछ आश्चर्यजनक है, लेकिन super()
भाषा में सबसे गलत तरीके से लागू कार्यों में से एक है। बस इंटरनेट पर पाए जाने वाले सभी गलत super(type(self), self)
या चालान पर एक नज़र डालें super(self.__class__, self)
; यदि उस कोड को कभी भी एक व्युत्पन्न वर्ग से बुलाया गया था तो आप एक अनंत पुनरावृत्ति अपवाद के साथ समाप्त हो जाएंगे । बहुत कम से कम सरलीकृत super()
कॉल, बिना तर्क के, उस समस्या से बचा जाता है ।
नाम के लिए के रूप में super_
; सिर्फ संदर्भ __class__
अपने विधि में के रूप में अच्छी तरह से और इसे फिर से काम करेंगे। यदि आप या तो आपके विधि में नाम super
या संदर्भ देखें तो सेल बनाया गया है __class__
:
>>> super_ = super
>>> class A(object):
... def x(self):
... print("No flipping")
...
>>> class B(A):
... def x(self):
... __class__ # just referencing it is enough
... super_().x()
...
>>> B().x()
No flipping