2009-10-11 9 views
6

पायथन में कक्षा निकाय में इसे परिभाषित करने के लिए __init__ में किसी सदस्य को परिभाषित करने के बीच अंतर?

class a: 
    def __init__(self): 
     self.val=1 

कर कर

class a: 
    val=1 
    def __init__(self): 
     pass 
+1

डुप्लिकेट http://stackoverflow.com/questions/1537202/variables-inside-and-outside-of-a-class-init-function –

+2

कुछ दिनों के भीतर एक ही प्रश्न? घर का पाठ? –

+0

कृपया मेरे द्वारा पोस्ट किए गए अन्य प्रश्नों पर एक नज़र डालें, उदाहरण के लिए: http://stackoverflow.com/questions/1547222/prevent-decorator-from-being-used-twice-on-the-same-function-in -पिथन या यह: http: // stackoverflow।कॉम/प्रश्न/1353173/यह-संभव-टू-एड-ए-फ्लैश-वीडियो-ऑन-ए-फोगबगज़-विकी-पेज (मुझे संदेह है कि कितने स्कूलों में एक फॉगबग खाता है :)) भी, अगर वहां है कोई भी स्थान जहां आप उपयोगकर्ता के आईपी देख सकते हैं - मुझे पूरा यकीन है कि दूसरा लड़का मेरे जैसा ही देश नहीं है। – olamundo

उत्तर

10
class a: 
    def __init__(self): 
     self.val=1 

इस एक वर्ग बनाता है (Py2, एक cruddy, विरासत, पुरानी शैली में, ऐसा नहीं करते हैं कि करने के लिए बीच क्या अंतर है ! वर्ग; पी 3 में, गंदा पुरानी विरासत कक्षाएं अंततः चली गई हैं, इसलिए यह एक और एकमात्र प्रकार का वर्ग होगा - ** अच्छा * दयालु, जिसके लिए पी 2 में class a(object): की आवश्यकता होती है) जैसे कि प्रत्येक उदाहरण शुरू होता है इसके ओउ एन पूर्णांक ऑब्जेक्ट 1 का संदर्भ।

class a: 
    val=1 
    def __init__(self): 
     pass 

इस (एक ही तरह के) एक वर्ग पैदा करता है जो अपने आप में पूर्णांक वस्तु 1 के लिए एक संदर्भ है (इसके उदाहरणों कोई प्रति-उदाहरण के संदर्भ के साथ शुरू)।

int मानों जैसे अपरिवर्तनीय के लिए, व्यावहारिक अंतर देखना मुश्किल है। उदाहरण के लिए, किसी भी मामले में, यदि आप बाद में self.val = 2a के एक उदाहरण पर करते हैं, तो यह उदाहरण संदर्भ (मौजूदा उत्तर इस संबंध में बुरी तरह गलत है) बना देगा।

म्यूटेबल ऑब्जेक्ट्स के लिए भेद महत्वपूर्ण है, क्योंकि उनके पास म्यूटेटर विधियां हैं, इसलिए यह जानना बहुत महत्वपूर्ण है कि कोई निश्चित सूची अद्वितीय प्रति उदाहरण है या सभी मामलों में साझा की गई है। लेकिन अपरिवर्तनीय ऑब्जेक्ट्स के लिए, क्योंकि आप ऑब्जेक्ट को कभी भी नहीं बदल सकते हैं, लेकिन केवल असाइन करें (उदा। self.val, जो हमेशा प्रति-उदाहरण संदर्भ बनाएगा), यह बहुत मामूली है। आप बाद में आवंटित a.val = 3, पहले मामले में इस को प्रभावित करेगा क्या उदाहरणों है कि उनके अपने self.valकरने के लिए सौंपा, या समकक्ष कार्यों के लिए किया था के लिए छोड़कर (प्रत्येक उदाहरण के द्वारा self.val के रूप में देखा है, तो:

बस immutables के लिए ही प्रासंगिक अंतर के बारे में

); दूसरे मामले में, यह किसी भी उदाहरण से self.val के रूप में देखा जाने वाला प्रभाव प्रभावित नहीं करेगा (उदाहरण के लिए जिनके लिए आपने del self.val या समकक्ष कार्रवाइयां की थीं)।

5

जैसा कि अन्य लोगों ने उल्लेख किया है, एक मामले में यह कक्षा पर एक विशेषता है उदाहरण के लिए एक विशेषता। क्या इससे कोई फर्क पड़ता है? हाँ, एक मामले में यह करता है। जैसा कि एलेक्स ने कहा, अगर मूल्य परिवर्तनीय है। सबसे अच्छा स्पष्टीकरण कोड है, इसलिए मैं इसे दिखाने के लिए कुछ कोड जोड़ूंगा (यह सब जवाब है, वास्तव में):

पहले दो वर्ग विशेषताओं को परिभाषित करने वाला वर्ग।

>>> class A(object): 
...  def __init__(self): 
...   self.number = 45 
...   self.letters = ['a', 'b', 'c'] 
... 

और फिर एक वर्ग दो वर्ग विशेषताओं को परिभाषित करता है।

>>> class B(object): 
...  number = 45 
...  letters = ['a', 'b', 'c'] 
... 

अब हम उन्हें इस्तेमाल:

>>> a1 = A() 
>>> a2 = A() 
>>> a2.number = 15 
>>> a2.letters.append('z') 

और सब कुछ ठीक है:

>>> a1.number 
45 
>>> a1.letters 
['a', 'b', 'c'] 

अब वर्ग विशेषता भिन्नता का उपयोग करें:

>>> b1 = B() 
>>> b2 = B() 
>>> b2.number = 15 
>>> b2.letters.append('z') 

और यह सब है .. .well ...

>>> b1.number 
45 
>>> b1.letters 
['a', 'b', 'c', 'z'] 

हाँ, ध्यान दें कि जब आप बदलते हैं, तो उत्परिवर्तनीय वर्ग विशेषता यह सभी वर्गों के लिए बदल जाती है। आमतौर पर यह नहीं है कि आप क्या चाहते हैं।

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

6

अन्य ने तकनीकी मतभेदों को समझाया है। मैं यह बताने की कोशिश करूंगा कि आप कक्षा चर का उपयोग क्यों कर सकते हैं।

यदि आप केवल कक्षा को तुरंत चालू कर रहे हैं, तो वर्ग चर प्रभावी ढंग से इंस्टेंस चर हैं। हालांकि, यदि आप कई प्रतियां बना रहे हैं, या कुछ मामलों के बीच राज्य साझा करना चाहते हैं, तो कक्षा चर बहुत आसान हैं। उदाहरण के लिए:

class Foo(object): 
    def __init__(self): 
     self.bar = expensivefunction() 

myobjs = [Foo() for _ in range(1000000)] 

महंगा कार्य() को दस लाख बार बुलाया जाएगा। यदि यह हर बार एक ही मूल्य वापस करने जा रहा है, तो डेटाबेस से कॉन्फ़िगरेशन पैरामीटर लाने का कहें, तो आपको इसे कक्षा परिभाषा में ले जाने पर विचार करना चाहिए ताकि इसे केवल एक बार बुलाया जा सके और फिर सभी मामलों में साझा किया जा सके।

मैं परिणामों को याद करते समय कक्षा चर का भी उपयोग करता हूं। उदाहरण:

class Foo(object): 
    bazcache = {} 

    @classmethod 
    def baz(cls, key): 
     try: 
      result = cls.bazcache[key] 
     except KeyError: 
      result = expensivefunction(key) 
      cls.bazcache[key] = result 
     return result 

इस मामले में, बाज एक वर्ग विधि है; इसका परिणाम किसी भी आवृत्ति चर पर निर्भर नहीं है। इसका मतलब है कि हम कक्षा चर में परिणाम कैश की एक प्रति रख सकते हैं, ताकि 1) आप एक ही परिणाम को कई बार स्टोर न करें, और 2) प्रत्येक उदाहरण अन्य परिणामों से कैश किए गए परिणामों से लाभ उठा सकता है।

उदाहरण के लिए, मान लें कि आपके पास लाखों उदाहरण हैं, प्रत्येक Google खोज के परिणामों पर परिचालन करते हैं। आप शायद अधिक पसंद करेंगे कि वे सभी ऑब्जेक्ट उन परिणामों को साझा करते हैं, जिनमें से प्रत्येक खोज को निष्पादित करता है और उत्तर की प्रतीक्षा करता है।

तो मैं यहां लैनर्ट से असहमत हूं। वर्ग चर बहुत कुछ मामलों में सुविधाजनक हैं। जब वे नौकरी के लिए सही उपकरण होते हैं, तो उनका उपयोग करने में संकोच न करें।

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

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