2011-12-23 18 views
18

ओपनस्टैक के कोड को पढ़ने के दौरान और मुझे इसका सामना करना पड़ा।ऑब्जेक्ट की __init __() विधि पाइथन में क्या करती है?

एक वर्ग 'सेवा' नामक आधार वर्ग 'वस्तु' विरासत में, और उसके बाद सेवा के __init__() विधि में, वस्तु की __init__ कहा जाता है। संबंधित कोड इस तरह दिखता है:

वर्ग परिभाषा:

class Service(object): 

और सेवा के init विधि परिभाषा:

def __init__(self, host, binary, topic, manager, report_interval=None, 
      periodic_interval=None, *args, **kwargs): 

और सेवा के init में सुपर ('वस्तु' यहाँ) के लिए एक कॉल :

super(Service, self).__init__(*args, **kwargs) 

मैं आखिरी कॉल समझ में नहीं आता, object.__init__() क्या यह वास्तविक करता है ly do? कोई भी मदद कर सकता है?

उत्तर

14

संक्षिप्त उत्तर है कि वस्तु .__ init __() विधि जाँच लें कि कोई तर्क में पारित कर दिया है सिवाय कुछ नहीं करता है। जानकारी के लिए the source देखें है।

जब सेवा का एक उदाहरण पर कहा जाता है, super() कॉल() आपत्ति उठाने .__ init __ प्रतिनिधि होगा और कुछ नहीं होगा।

हालांकि, सेवा के उप-वर्ग के उदाहरण पर कॉल करने पर, चीजें अधिक दिलचस्प होती हैं। सुपर() कॉल संभावित रूप से ऑब्जेक्ट के अलावा किसी भी वर्ग में प्रतिनिधि हो सकता है, जो कि उदाहरण के अभिभावक वर्ग है लेकिन सेवा का अभिभावक नहीं है। यह कैसे काम करता है और यह उपयोगी क्यों है, इस बारे में विवरण के लिए, ब्लॉग पोस्ट Python's Super Considered Super देखें!

निम्न उदाहरण (कुछ काल्पनिक) दिखाता है कि कैसे सेवा का एक उपवर्ग सेवा में सुपर कॉल पैदा कर सकता है एक और वर्ग रंग कहा जाता है के लिए निर्देशित किया है:

class Service(object): 
    def __init__(self, host, binary, topic, manager, report_interval=None, 
      periodic_interval=None, *args, **kwargs): 
     print 'Initializing Service' 
     super(Service, self).__init__(*args, **kwargs) 

class Color(object): 
    def __init__(self, color='red', **kwargs): 
     print 'Initializing Color' 
     self.color = color 
     super(Color, self).__init__(**kwargs) 

class ColoredService(Service, Color): 
    def __init__(self, *args, **kwds): 
     print 'Initializing Colored Service' 
     super(ColoredService, self).__init__(*args, **kwds) 

c = ColoredService('host', 'bin', 'top', 'mgr', 'ivl', color='blue') 

में उदाहरण, प्रारंभिक क्रम निम्न क्रम में होते हैं:

  1. रंगीन प्रारंभ करना सेवा
  2. प्रारंभ करने सेवा
  3. प्रारंभ करने का रंग
  4. प्रारंभ वस्तु - तर्क
+2

संदर्भ [पायथन के सुपर कंसिडेड सुपर] (http://rhettinger.wordpress.com/2011/05/26/super-Considered-super/) बहुत मदद करता है। धन्यवाद! –

+1

'रंगीन सेवा' कन्स्ट्रक्टर उदा। 'foo = 'bar'' को पारित किया जाना है, लेकिन यह अंततः' TypeError: object .__ init __() के साथ विफल हो जाएगा कोई पैरामीटर नहीं लेता है। तो 'सेवा' और 'रंग' कक्षाओं के लिए 'सुपर' कॉल में '* args' और' ** kwargs' को पारित करने का क्या मतलब है? आपका उदाहरण उनके बिना वही काम करेगा (और अधिक मजबूत होगा)। – ekhumoro

+0

@ekhumoro उस टिप्पणी को ओपनस्टैक के लेखकों पर निर्देशित किया जाना चाहिए। '' * Args'' भाग उनके कोड से था और कॉलर्स को उस हस्ताक्षर का सम्मान करना होगा। मैंने * रंग * और * रंगीन सेवा * को यह दिखाने के लिए जोड़ा कि एमआरओ * सेवा * से * रंग * से * ऑब्जेक्ट * तक कैसे श्रृंखला कर सकता है। –

3

super()हमेशा माता-पिता वर्ग के लिए प्रॉक्सी नहीं लौटाता है। इसके बजाय, यह MRO में अगली कक्षा के लिए एक प्रॉक्सी देता है। एकल विरासत में एमआरओ और विरासत श्रृंखला के बीच कोई अंतर नहीं है। एकाधिक विरासत में, एमआरओ के परिणामस्वरूप अन्य विरासत श्रृंखला के बजाय कक्षा में परिणाम हो सकता है।

+0

लेकिन कोई बहु-भाग यहाँ है, सेवा वस्तु –

+0

@can से सीधे विरासत के रूप में जाँच छोड़कर कुछ भी नहीं कर रही है लेकिन क्या .: विरासत 'सेवा' से? –

+0

मैंने एमआरओ के बारे में लेख पढ़ा है, और मुझे लगता है क्योंकि सेवा सीधे वस्तु से विरासत में आती है, सुपर() में कोई अस्पष्टता नहीं है। सेवा से विरासत में विरासत में कोई फर्क नहीं पड़ता है। –

1

object.__init__() वास्तव में कुछ भी नहीं है लेकिन super() कॉल शामिल किया जाना चाहिए, जब भी एक वर्ग केवल object एक सुपर क्लास के रूप में है।

One big problem with 'super' is that it sounds like it will cause the superclass's copy of the method to be called. This is simply not the case, it causes the next method in the MRO to be called (...) People omit calls to super(...).init if the only superclass is 'object', as, after all, object.init doesn't do anything! However, this is very incorrect. Doing so will cause other classes' init methods to not be called.

http://fuhm.net/super-harmful/

+0

लेकिन ध्यान दें कि ओपी का उदाहरण कोड असफल हो जाएगा यदि कुछ * 'args' और' ** kwargs' के माध्यम से पारित हो जाता है (जब तक कि यह पाइथन 2.5 या इससे पहले तक चलता है)। – ekhumoro

+0

क्या आप दो और विवरणों के साथ अपने विचारों को समझा सकते हैं? @ekhumoro –

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