2015-12-15 12 views
9

क्या कोई मुझे निम्नलिखित कोड समझा सकता है।पायथन में कक्षा के अलग-अलग उदाहरण कैसे बनाएं?

class InnerTest: 

    def __init__(self, value = 0): 
     self.value = value 

class OuterTest: 

    def __init__(self, inner_test = InnerTest()): 
     self.inner_test = inner_test 

a = OuterTest() 
b = OuterTest() 

a.inner_test.value = 42 
print b.inner_test.value 

यह 42 प्रिंट, मैं उम्मीद 0.

मैं OuterTest के दो उदाहरणों, जो InnerTest प्रत्येक का एक विशिष्ट उदाहरण होते हैं बनाने के लिए मतलब है। इसके बजाय मुझे ऑउटरटेस्ट के दो उदाहरण मिले जो इनरटेस्ट के उसी उदाहरण का संदर्भ देते हैं।

इसके अलावा जो भी मैं चाहता हूं उसे लागू करने का एक सही तरीका क्या होगा?

उत्तर

10

फ़ंक्शन परिभाषा के समय फ़ंक्शंस में डिफ़ॉल्ट पैरामीटर का मूल्यांकन केवल एक बार किया जाता है। तो ऑब्जेक्ट दोनों के लिए InnerTest का केवल एक उदाहरण उपयोग किया जा रहा है।

a = OuterTest() 
b = OuterTest() 

दोनों, a.inner_test और b.inner_test, एक ही उदाहरण की बात कर रहे है, और इसलिए परिणाम:

इसका मतलब है कि, जब आप दो वस्तुओं पैदा करते हैं।

इस को हल करने के None को डिफ़ॉल्ट मान बदलने के लिए, और सशर्त उदाहरण बनाने के लिए:

class OuterTest: 
    def __init__(self, inner_test=None): 
     if not inner_test: 
      inner_test = InnerTest() 
     self.inner_test = inner_test 
+1

@ पैड्राइक कनिंघम आपको जरूरी तर्क पारित करने की आवश्यकता नहीं है। इस मामले में, यह 'कोई नहीं' होगा, और फिर आप इसे फ़ंक्शन में प्रारंभ कर सकते हैं। –

+1

@ पैड्राइक कनिंघम नहीं, यह मुद्दा समान नहीं है। यदि मान 'कोई नहीं' है, तो 'ए' और 'बी' दोनों में, यह' if' के अंदर' इनरटेस्ट 'के 2 अलग-अलग उदाहरण बनाएगा। –

+0

यह सही उत्तर है: यह बताता है कि क्या हो रहा है, और डिफ़ॉल्ट पैरामीटर की सुविधा को बनाए रखते हुए अलग-अलग उदाहरण बनाने के लिए व्यावहारिक समाधान प्रदान करता है। धन्यवाद। – marcv81

2

आप InnerTest() को इनिट में स्थानांतरित कर सकते हैं या इसे दूसरे मामले में कक्षा एन के संदर्भ में पारित करने के लिए इनिट में कॉल कर सकते हैं। इसलिए वस्तु यह एक class attribute बनाने के रूप में init में यह instantiating द्वारा एक उदाहरण विशेषता के लिए विरोध OuterTest वर्ग के सभी उदाहरणों बीच साझा किया जाता

def __init__(self, inner_test = InnerTest()): का उपयोग करते हुए एक बार मूल्यांकन किया जाता है।

class OuterTest: 
    def __init__(self): 
     self.inner_test = InnerTest() 

या: के रूप में वांछित

class OuterTest: 
    def __init__(self, inner_test = InnerTest): 
     self.inner_test = inner_test() 

दोनों ही तरीकों से काम करेंगे, एक वर्ग के लिए एक संदर्भ गुजर मतलब है कि आप में से गुजर का विकल्प होता है जो कुछ वर्ग आप चाहते हैं:

In [11]: class OuterTest: 
    ....:  def __init__(self, inner_test=InnerTest): 
    ....:    self.inner_test = inner_test() 
    ....:   

In [12]: a = OuterTest() 

In [13]: b = OuterTest() 

In [14]: a.inner_test.value = 42 

In [15]: print(a.inner_test.value) 
42 

In [16]: print(b.inner_test.value) 
0 

In [17]: class OuterTest: 
    ....:  def __init__(self): 
    ....:    self.inner_test = InnerTest() 
    ....:   

In [18]: a = OuterTest() 

In [19]: b = OuterTest() 

In [20]: a.inner_test.value = 42 

In [21]: print(a.inner_test.value) 
42 

In [22]: print(b.inner_test.value) 
+0

दूसरा समाधान नहीं है कि मैं क्या चाहता हूँ, लेकिन पहले एक अच्छी तरह से काम करता है। क्या आपको कोई विचार होगा कि मेरा मूल कोड ऐसा नहीं करता है जो मैं चाहता हूं? – marcv81

+0

आंतरिक_टेक्स्ट पैरामीटर वैकल्पिक बनाने का अर्थ है कि वह एक तत्काल वस्तु को पैरामीटर के रूप में पास करना चाहता है। यह आपके उत्तर के साथ काम करेगा? –

+0

@ marcv81, यह अनिवार्य रूप से एक वर्ग के बीच अंतर है –

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