2011-02-03 16 views
8

जब एक उप कक्षा में एक विधि अधिभावी मैं अक्सर ऐसा करते हैं:शॉर्टकट

def method_x(self): 
    x = super(type(self), self).method_x() 

    [Some extra code] 
    return x 

मेरे सवाल यह है: वहाँ (सुपर के लिए एक शॉर्टकट प्रकार (आत्म है) , स्वयं)?

+14

इसे पढ़ने वाले किसी को भी चेतावनी: उपर्युक्त कोड * गलत * है। नकल मत करो! –

+0

ग्लेन, डंकन: यह इंगित करने के लिए धन्यवाद कि यह गलत है। मुझे अपना कोड grep करना होगा और इसे बदलना होगा। –

+0

@Glenn Maynard: सुनिश्चित नहीं है कि मैं समझता हूं कि आप इसे क्यों गलत मानते हैं *। 'सुपर (स्वयं .__ वर्ग__, स्वयं) 'का उपयोग करना बेहतर होगा? – martineau

उत्तर

17

ऐसा न करें: यदि super केवल type(self) का उपयोग अपने पहले तर्क के रूप में कर सकता है तो इसे पहले स्थान पर दो तर्क लेने के लिए लिखा नहीं गया होगा। आपको यहां वास्तविक वर्ग को एक अभिव्यक्ति नहीं देनी चाहिए जो वर्ग को उप-वर्गीकृत किया जा सकता है।

सुपर विधि के लिए पहला तर्क वर्तमान विधि परिभाषा वाला वर्ग होना चाहिए क्योंकि आप सुपर को कह रहे हैं जहां बेस की सूची में अपनी खोज शुरू करने के लिए।

पायथन 3 इसके बारे में जानता है और संकलन समय पर super() जादुई रूप से व्यवहार करता है, लेकिन पायथन 2.x में यह केवल एक सामान्य कार्य है, इसलिए इसका पैरामीटर स्वयं को समझने का कोई तरीका नहीं है।

[मेरे प्रारंभिक बिंदुओं में जोड़ने के लिए संपादित करें] वास्तव में, पाइथन 2.x में super() का उपयोग करने के लिए एक और कम उपयोग किया जाने वाला तरीका है। आप सुपर के एक अनबाउंड फार्म का उपयोग करें और यह बाध्य हो सकता है जब आप इसे उपयोग:

>>> class A(object): 
    def foo(self): 
     print "A.foo" 


>>> class B(A): 
    def foo(self): 
     self.__super.foo() 
     print "B.foo" 


>>> B._B__super = super(B) 
>>> class C(A): 
    def foo(self): 
     self.__super.foo() 
     print "C.foo" 


>>> C._C__super = super(C) 
>>> class D(C,B): pass 

>>> D._D__super = super(D) 
>>> D().foo() 
A.foo 
B.foo 
C.foo 

यहाँ एक महत्वपूर्ण कमी है: आप प्रत्येक super वस्तु है, जो आप का उपयोग करके ऐसा कर सकते हैं स्टोर करने के लिए एक अलग नाम का उपयोग करना self.__super, लेकिन आप क्लास परिभाषा में सीधे एक अनबाउंड super नहीं बना सकते हैं (क्योंकि यदि आप अभी तक मौजूद नहीं हैं तो आप कक्षा का नाम नहीं दे सकते हैं) और यदि आप इसे बाहर बनाते हैं तो आपको यह सुनिश्चित करने के लिए मैन्युअल रूप से नाम को खराब करना होगा ताकि आप सही सेट कर सकें कक्षा के लिए __super वस्तु। पायथन 2.6 के लिए और बाद में आप इसे कक्षा सजावट के रूप में लपेट सकते हैं।

+1

मैं इसकी सिफारिश करने के खिलाफ सिफारिश करता हूं; यह कुछ असामान्य करने के लिए एक जीत नहीं है। –

+2

हां, यह गन्दा है जो शायद कम इस्तेमाल होता है, लेकिन मैंने सोचा कि मुझे इसे एक विकल्प के रूप में उल्लेख करना चाहिए। पाठ्यक्रम का एक बेहतर विकल्प सिर्फ Python 3.x का उपयोग करना है (इसके लिए आपको जो भी लाइब्रेरी चाहिए, उसका समर्थन करने के अधीन) – Duncan

+0

मैंने आज python3 का उपयोग करने पर देखा। मैं पिलोन पिरामिड का उपयोग कर रहा हूं और यह और इसकी कुछ निर्भरता अभी तक py3 का समर्थन नहीं करती है, इसलिए मुझे कुछ महीनों में वापस जांचना होगा। –

संबंधित मुद्दे