2013-12-18 8 views
28

में प्रारंभ किया जाना चाहिए, शायद यह एक तकनीकी से अधिक स्टाइल प्रश्न है लेकिन मेरे पास कई सदस्य चर के साथ एक अजगर वर्ग है और मैं इसे काम करना चाहता हूं ताकि कुछ सदस्य चर प्रारंभिक जब उपयोगकर्ता पहली बार कक्षा का उदाहरण बनाता है (यानी __init__ फ़ंक्शन में) और मैं चाहता हूं कि अन्य सदस्य चर सदस्य सदस्य कार्यों के तर्कों से परिभाषित किए जाएं जिन्हें बाद में कॉल किया जाएगा। तो मेरा सवाल है कि क्या मुझे __init__ फ़ंक्शन में सभी सदस्य चर प्रारंभ करना चाहिए (और उन लोगों को सेट करें जिन्हें बाद में डमी मानों पर परिभाषित किया जाएगा) या __init__ फ़ंक्शन में कुछ प्रारंभ करें और कुछ बाद के कार्यों में। मुझे एहसास है कि यह समझना मुश्किल हो सकता है, इसलिए यहां कुछ उदाहरण दिए गए हैं।पायथन - सभी सदस्य चर को __init__

इस उदाहरण में var3__init__ फ़ंक्शन में प्रारंभ में 0 पर सेट है, फिर बाद में my_funct फ़ंक्शन में वांछित मान पर सेट करें।

class myClass(object): 
    def __init__(self,var1,var2): 
     self.var1=var1 
     self.var2=var2 
     self.var3=0 

    def my_funct(self,var3): 
     self.var3=var3 

और इस उदाहरण में, var3__init__ समारोह में सभी में परिभाषित नहीं है

class myClass(object): 
    def __init__(self,var1,var2): 
     self.var1=var1 
     self.var2=var2 

    def my_funct(self,var3): 
     self.var3=var3 

मुझे नहीं लगता कि किसी भी तरह से एक बड़ा अंतर (शायद स्मृति के उपयोग में एक मामूली अंतर) बनाना होगा । लेकिन मैं सोच रहा था कि इनमें से किसी एक कारण से दूसरे में से एक को प्राथमिकता दी जाती है।

उत्तर

19

ऑब्जेक्ट उन्मुख प्रोग्रामिंग में यह डेवलपर पर निर्भर करता है कि यह सुनिश्चित करने के लिए कि ऑब्जेक्ट हमेशा तत्काल स्थिति में होता है और विधि समाप्त होने के बाद होता है। इसके अलावा आप अपनी इच्छानुसार कक्षा विकसित करने के लिए स्वतंत्र हैं (कुछ सिद्धांतों को उप-वर्गीकरण/ओवरराइडिंग के साथ ध्यान में रखते हुए)।

Pylint जैसे टूल __init__ के बाहर इंस्टेंस चर सेट करते समय चेतावनी देंगे। यह तर्क दिया जा सकता है कि __init__ में सभी इंस्टेंस चर सेट करना क्लीनर है लेकिन यह ऐसा नियम नहीं है जिसे हर समय पालन किया जाना चाहिए।

+1

सहमत। संगठनात्मकता महत्वपूर्ण है - आप नहीं चाहते हैं कि बाहरी लोग आपके एपीआई या कक्षा का उपयोग अमान्य स्थिति में करें। –

+0

क्या आप संक्षेप में परिभाषित कर सकते हैं कि 'सुसंगत राज्य' का अर्थ क्या है। क्या इसका मतलब है कि तत्कालता के बाद कोई नया सदस्य चर जोड़ा जाना चाहिए? – user1893354

+1

@ user1893354 आप तत्कालता के बाद चर जोड़ सकते हैं लेकिन ऑब्जेक्ट बनाने, एक या अधिक तरीकों को कॉल करना और गन्दा वस्तु के साथ समाप्त होना संभव नहीं होना चाहिए। विधियों और उनके वापसी मूल्यों का व्यवहार हमेशा सुसंगत होना चाहिए। उदाहरण के लिए, हमारे पास 'कार' श्रेणी नहीं हो सकती है जो रिपोर्ट करता है कि "टूटा हुआ" और "ठीक से काम करना" दोनों हो। –

3

मैं वास्तव में उन वैरिएबल को हतोत्साहित करता हूं जिन्हें आपको __init__ में मनमाने ढंग से डिफ़ॉल्ट मान में हमेशा आवश्यकता नहीं होती है।

यदि यह मामला है, तो मैं ओओ के आपके उपयोग पर सवाल करता हूं, लेकिन मुझे यकीन है कि एक वैध और समझने योग्य मामला है जहां __init__ सब कुछ नहीं करेगा, और कक्षा अतिरिक्त विशेषताओं को जोड़कर स्वयं को संशोधित करना चाहेंगे अन्य तरीकों।

यह जांचने के लिए मेरी राय में उचित तरीका है कि एक चर चलाने के दौरान एक चर सेट किया गया था, जिसका उपयोग hasattr का उपयोग करना होगा। यह इस मामले में है कि यह विधि का उपयोग करने का एक वैध तरीका है और परीक्षण सिर्फ एक समझदार तरीके से व्यवहार को स्विच करता है।

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

अर्थात अरे यार, तुम वर्ग को प्रारंभ किया था, लेकिन क्या आप वाकई z विशेषता z_run विधि चलाने से पहले z_init विधि को फोन करके मौजूद है बनाने की जरूरत है।

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

कारण मुझे मनमानी चूक के लिए चर शुरू करने के विचार को पसंद नहीं है यह भ्रमित हो सकता है (क्योंकि यह मनमाना है) और लाइन शोर है।

यदि मान है नहीं मनमाने ढंग से और बस एक डिफ़ॉल्ट मान है कि आप __init__ विधि है कि अधिरोहित जा सकता है में एक डिफ़ॉल्ट मान का उपयोग करना चाहिए बदला जा सकता है। यह वास्तव में एक वैध प्रारंभिक स्थिति भी हो सकता है, जो मनमाने ढंग से नहीं है और आपको इसे __init__ विधि में सेट करना चाहिए।

तो असली जवाब है यह निर्भर करता है, और आप शायद यह से बचने और अगर आप या तो अन्य तरीकों में विशेषताएं जोड़ना या मनमाने ढंग मूल्यों के गुण आरंभ से यह कर रहे हैं OO के आपके उपयोग सवाल करना चाहिए।

जबकि शिमोन विसार आपके ऑब्जेक्ट को एक सतत स्थिति में रखने के लिए कह रहा है, उसके पास आपके सार तत्व पर आधारित स्थिरता के आधार पर कोई आधार नहीं है। जबकि पिलिंट इस तरह की चीज पर चेतावनी देता है, लिंट कार्यक्रमों से चेतावनियां बस इतनी उच्च स्तर की समीक्षाकर्ता को उन चीजों से सतर्क किया जा सकता है जो आमतौर पर कोड गंध इंगित करते हैं। मैं उच्च स्तरीय समीक्षक कहता हूं क्योंकि एक वास्तविक समीक्षक को आपके सभी कोड को पढ़ना और समझना चाहिए, और इस प्रकार वास्तव में पिलिंट की आवश्यकता नहीं है।

एक उदाहरण है कि अंगूठे का नियम टूट जाता है:

class Mutant(object): 
    """A mutant!""" 

    def __init__(self): 
     """A mutant is born with only 1 eye and 1 mouth""" 

     self.eyes = 1 
     self.mouth = 1 
     self.location = 'Montana' 

    def roll_to(self, location): 
     """If they have limbs, running is less dangerous""" 

     if hasattr(self, 'limbs'): 
      print 'Your mutant broke its limbs off!!' 
      del self.limbs 

     self.location = location 

    def run_to(self, location): 
     """If they don't have limbs, running is not effective""" 

     if not hasattr(self, 'limbs'): 
      print 'Your mutant tries to run but he has no limbs.' 
     else: 
      self.location = location 

    def grow_limbs(self, number_of_limbs): 
     """Ah, evolution!""" 

     assert number_of_limbs > 0, 'Cannot grow 0 or less limbs...' 

     if hasattr(self, 'limbs'): 
      self.limbs += number_of_limbs 
     else: 
      self.limbs = number_of_limbs 
+0

अच्छे अंक। मैं उस मामले के बारे में सोच रहा था जहां सदस्य चर में से एक सदस्य फ़ंक्शन का आउटपुट है जिसे आप ऑब्जेक्ट में सहेजना चाहते हैं। इस मामले में, सदस्य फ़ंक्शन को कॉल करने के बाद चर को केवल वास्तविक मान के साथ तुरंत चालू किया जा सकता है। – user1893354

+0

तो, मुझे यह सुनिश्चित करने दें कि मैं आपको सही तरीके से समझता हूं ... उदाहरण के लिए, 'obj' में 'output_complex_calculation' है, और आप' obj.set_result_of_complex_calculation (obj.output_of_complex_calculation())' –

+0

उदाहरण के लिए, यदि आपके पास है वर्ग जो भविष्यवाणी मॉडल है जहां उपयोगकर्ता तत्कालता पर मॉडल के पैरामीटर इनपुट करता है। फिर उपयोगकर्ता .predict() फ़ंक्शन को कॉल करता है जो भविष्यवाणियों की एक सूची बनाता है। लेकिन आप इस ऑब्जेक्ट के लिए सदस्य चर के रूप में इन भविष्यवाणियों को सहेजना चाहते हैं। तो हो सकता है कि कुछ अन्य सदस्य फ़ंक्शन इस नए भविष्यवाणी सदस्य चर के साथ कुछ करेंगे। तो इस मामले में, पूर्वानुमान सदस्य चर के लिए वास्तविक मूल्य केवल तत्काल हो सकते हैं। भविष्यवाणी() को बुलाया जाता है। – user1893354

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