2012-01-13 8 views
23

का उपयोग कर अजगर में विशेषताओं की विरासत मैं जावा व्यक्ति हूं जिसने अभी पाइथन सीखना शुरू किया है। इस उदाहरण लें:__init__

class Person(): 
    def __init__(self, name, phone): 
     self.name = name 
     self.phone = phone 

class Teenager(Person): 
    def __init__(self, name, phone, website): 
     self.name=name 
     self.phone=phone 
     self.website=website 

मैं वहाँ अनावश्यक कोड (मैं जावा में पता है, वहाँ ऊपर कोड की बिट के लिए अतिरेक के एक बहुत हैं) के लिए बहुत कुछ है यकीन है।

कौन सा भागों संबंध में अनावश्यक हैं पहले से ही माता पिता वर्ग से लिए गए हैं जिसके गुणधर्मों के लिए?

उत्तर

29

पाइथन में कक्षा के लिए __init__ फ़ंक्शन लिखते समय, आपको हमेशा अपने सुपरक्लास के __init__ फ़ंक्शन को कॉल करना चाहिए। हम प्रासंगिक विशेषताएं सुपर क्लास के लिए सीधे पारित करने के लिए इसका उपयोग कर सकते हैं, इसलिए अपने कोड इस तरह दिखेगा:

class Person(object): 
    def __init__(self, name, phone): 
     self.name = name 
     self.phone = phone 
class Teenager(Person): 
    def __init__(self, name, phone, website): 
     Person.__init__(self, name, phone) 
     self.website=website 

के रूप में अन्य लोगों ने बताया है, तो आप

के साथ लाइन

Person.__init__(self, name, phone) 

बदल सकते

super(Teenager, self).__init__(name, phone) 

और कोड एक ही बात करेंगे। ऐसा इसलिए है क्योंकि पाइथन instance.method(args) में Class.method(instance, args) के लिए सिर्फ लघुरूप है। यदि आप super का उपयोग करना चाहते हैं तो आपको यह सुनिश्चित करना होगा कि आपने object को Person के लिए बेस क्लास के रूप में निर्दिष्ट किया है जैसा मैंने अपने कोड में किया है।

python documentation कैसे super कीवर्ड का उपयोग करने के बारे में अधिक जानकारी नहीं है। इस मामले में महत्वपूर्ण बात यह है कि यह अजगर बताता self की एक सुपर क्लास कि नहीं है Teenager

+2

ध्यान दें कि यदि आप पाइथन 2.x का उपयोग कर रहे हैं, तो आपको 'सुपर()' का उपयोग करने के लिए 'व्यक्ति' की मूल श्रेणी के रूप में स्पष्ट रूप से 'ऑब्जेक्ट' सूचीबद्ध करना होगा। अन्यथा, आपको 'व्यक्ति .__ init__' फ़ॉर्म का उपयोग करना होगा। – chepner

+0

@chepner क्या आप इसके लिए एक संदर्भ प्रदान कर सकते हैं? मुझे एक नहीं मिल रहा है। – murgatroid99

+0

http://docs.python.org/library/functions.html#super इंगित करता है कि सुपर() केवल नए-शैली वर्गों पर समर्थित है, जो Python 2.x में हैं जो 'ऑब्जेक्ट' – chepner

5

अजगर में गुण नहीं ली गई है, जब वे निर्माता और माता पिता के वर्ग निर्माता में परिभाषित कर रहे हैं नहीं बुलाया जाता है में विधि __init__ देखने के लिए है , जब तक आप स्वयं यह सब करने के:

उस पर
class Person(): 
    def __init__(self, name, phone): 
     self.name = name 
     self.phone = phone 
class Teenager(Person): 
    def_init_(self, name, phone, website): 
     Person.__init__(self, name, phone) # Call parent class constructor. 
     self.website=website 

अधिक यहाँ: http://docs.python.org/tutorial/classes.html#inheritance

1

__init__, एक जावा निर्माता के विपरीत, स्वचालित रूप से वंशानुगत पदानुक्रम में हर वर्ग के लिए नहीं बुलाया जाता है - आप टी की जरूरत है ओ यह खुद करो।

इसके अलावा, आपके सभी ऑब्जेक्ट पदानुक्रमों को object (विशेष मामलों को छोड़कर) पर रूट किया जाना चाहिए।

आपका कोड पढ़ना चाहिए:

class Person(object): 
    def __init__(self, name, phone): 
     self.name = name 
     self.phone = phone 
class Teenager(Person): 
    def_init_(self, name, phone, website): 
     super(Teenager, self).__init__(name, phone) 
     self.website=website 

super इसकी दूसरा तर्क (self) है, जो कार्यों की सूची में अगले समारोह कॉल करेंगे प्रत्येक नाम ("विधि संकल्प आदेश के लिए कॉल करने के लिए एक प्रतिनिधि बनाता है ")। यह सुपरक्लास विधि को कॉल करने जैसा ही नहीं है, जैसा कि जावा में होता है।

तुम भी super(type(self), self).__init__(name, phone) लिख सकता है, लेकिन अगर आप इस वर्ग से आगे के वारिस, type(self)Teenager नहीं हो सकता है, और आप एक अनंत प्रत्यावर्तन हो सकता था। यह इस तथ्य का एक व्यावहारिक परिणाम है कि आप एक सुपरक्लस कन्स्ट्रक्टर को सीधे कॉल करने के बजाय एमआरओ के साथ एक प्रतिनिधि वस्तु के साथ काम कर रहे हैं।

11

थोड़ा क्लीनर तरह से मैं यह करना चाहते:

class Teenager(Person): 
     def __init__(self, *args, **kwargs): 
      self.website=kwargs.pop('website') 
      super(Teenager, self).__init__(*args, **kwargs) 

यह इस मामले में बहुत अधिक अंतर नहीं है, लेकिन जब आप तर्कों की एक टन के साथ एक __init__ है, यह जीवन को आसान बना देता है।

+0

* args और ** kwargs (... कई तर्कों के मामले में कुशल) के उपयोग के लिए उपरोक्त। –

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