2013-07-09 11 views
5

मैं प्रोग्रामिंग के लिए बहुत नया हूं और पाइथन सीखना शुरू कर दिया हूं। बहुत बेवकूफ सवाल लग सकता है, तो कृपया मेरी अज्ञान क्षमा करें। पर विचार करें निम्नलिखित स्निपेट:पाइथन वर्ग विशेषताओं को समझना

class Test1: 
    bar = 10  
    def display(self,foo): 
     self.foo=foo 
     print "foo : ",self.foo #80 
    def display1(self): 
     print "bar: ", self.bar #10 
     print "again foo: ", self.foo #80 

if __name__ == '__main__': 
    test1 = Test1() 
    test1.display(80) 
    test1.display1() 
    print test1.bar #10 
    print test1.foo #80 

मैं समझने के लिए के रूप में क्षेत्र में बुद्धिमान वे की तुलना में सभी स्थानों पर समान रूप से सुलभ हैं (जहां हम उन्हें परिभाषित किया है करने के लिए wrt) foo और पट्टी का उपयोग कर के बीच अंतर है चाहता हूँ एक-दूसरे और केवल अंतर यह है कि एक कार्य के अंदर है और दूसरा कक्षा के अंदर है लेकिन वे दोनों अभी भी "इंस्टेंस" चर हैं। तो कौन सा अच्छा अभ्यास है?

इसके अलावा, अगर मैं थोड़ा नीचे के रूप में प्रदर्शन समारोह को संशोधित:

def display(self,foo): 
     self.foo=foo 
     foo = foo 
     print "self.foo : ",self.foo 
     print "foo : ",foo 

किसी कृपया व्याख्या कर सकते हैं कि कैसे अजगर यह, देखता है क्या अंतर/महत्व इस self कीवर्ड दो foo के बीच में ला रहा है के रूप में।

+4

नहीं, 'बार' * एक आवृत्ति चर नहीं है। दोनों बहुत अलग हैं, यही कारण है कि यह "अच्छी प्रथा" के बारे में नहीं है। यह आपकी स्थिति के लिए उपयुक्त है, क्योंकि वे विभिन्न उद्देश्यों की सेवा करते हैं। – phant0m

+1

इसके अलावा 'self.bar' काम करता है क्योंकि नाम' बार' पहले उदाहरण के नामस्थान में और फिर कक्षा में खोजा जाता है। तथ्य यह है कि 'self.bar' काम * हमेशा * का मतलब नहीं है कि' बार' एक आवृत्ति चर है। – ersran9

उत्तर

3

bar एक वर्ग विशेषता है। में कक्षाओं के बाद से पायथन वस्तुएं हैं, उनके पास विशेषताओं भी हो सकते हैं। bar बस उस Test ऑब्जेक्ट पर रहने के लिए होता है, उदाहरण नहीं।

पाइथन विशेषता लुकअप को हल करने के तरीके के कारण, ऐसा लगता है कि test1 में bar विशेषता है, लेकिन ऐसा नहीं है।

foo दूसरी ओर पर कॉल करने के बाद उदाहरण test1 पर रहता है। इसका मतलब है कि Test के विभिन्न उदाहरणों में उनके संबंधित foo विशेषताओं में अलग-अलग मान हो सकते हैं।

बेशक, आप वर्ग चर का उपयोग किसी प्रकार के "साझा डिफ़ॉल्ट मान" के रूप में कर सकते हैं, जिसे आप एक उदाहरण विशेषता के साथ "ओवरराइड" कर सकते हैं, लेकिन यह भ्रमित हो सकता है।

दूसरा सवाल

def display(self,foo): 
    self.foo=foo 
    foo = foo 
    print "self.foo : ",self.foo 
    print "foo : ",foo 

चलो अभी जिस तरह से बाहर एक विवरण प्राप्त: self शब्द नहीं है, यह सिर्फ सम्मेलन पहला तर्क "स्व" कॉल करने के लिए है, तो आप भी इसे "इस कह सकते हैं "या" वह "या" बार "अगर आपको पसंद आया, लेकिन मैं इसकी अनुशंसा नहीं करता।

पायथन ऑब्जेक्ट पास करेगा, जिस पर विधि को पहला तर्क कहा जाता था।

def display(self,foo): 

यह foo प्रदर्शन उदाहरण-फ़ंक्शन के पहले पैरामीटर का नाम है।

self.foo=foo 

इस उदाहरण का नाम "foo", जिस पर आप मूल्य है, जो आप पहले तर्क के रूप में पारित करने के लिए कहा जाता है display() साथ विशेषता सेट करता है। अपने उदाहरण का प्रयोग test1.display(80), selftest1, foo80 और test1.foo इस प्रकार 80 पर सेट किया जाएगा।

foo = foo 

यह कुछ भी नहीं करता है। यह पहले पैरामीटर foo का संदर्भ देता है।

अगली दो पंक्तियां फिर से आवृत्ति चर foo और पहले पैरामीटर foo का संदर्भ देती हैं।

4

bar एक वर्ग विशेषता है और foo एक उदाहरण विशेषता है। मुख्य अंतर यह है कि bar जबकि foo एक उदाहरण के लिए उपलब्ध होगा ही अगर आपको लगता है कि उदाहरण के

>>> ins1 = Test1() 

ins1.bar ठीक काम करता है पर प्रदर्शन के फोन से कक्षा के सभी उदाहरणों लिए उपलब्ध हो जाएगा, क्योंकि यह एक वर्ग विशेषता है और सभी के द्वारा साझा किया जाता है उदाहरणों।

>>> ins1.bar 
10 

लेकिन आप foo सीधे यहाँ तक नहीं पहुँच सकता, क्योंकि यह अभी तक परिभाषित नहीं है:

>>> ins1.foo 
Traceback (most recent call last): 
    File "<ipython-input-62-9495b4da308f>", line 1, in <module> 
    ins1.foo 
AttributeError: Test1 instance has no attribute 'foo' 

>>> ins1.display(12) 
foo : 12 
>>> ins1.foo 
12 

आप कुछ उदाहरण जिम्मेदार बताते हैं जब उदाहरण तो बनाई गई है उन्हें __init__ विधि के अंदर जगह को प्रारंभ करना चाहते हैं ।

class A(object): 
    bar = 10 
    def __init__(self, foo): 
     self.foo = foo #this gets initialized when the instance is created 
    def func(self, x): 
     self.spam = x #this will be available only when you call func() on the instance 
...   
>>> a = A(10) 
>>> a.bar 
10 
>>> a.foo 
10 
>>> a.spam 
Traceback (most recent call last): 
    File "<ipython-input-85-3b4ed07da1b4>", line 1, in <module> 
    a.spam 
AttributeError: 'A' object has no attribute 'spam' 

>>> a.func(2) 
>>> a.spam 
2 
+1

मुझे लगता है कि * मुख्य * अंतर यह है कि एक वर्ग विशेषता "साझा" है, न कि यह सभी मामलों के लिए उपलब्ध है। – phant0m

1

व्यक्तिगत रूप से, मैं __init__ से या इसके बाद के अपने उदाहरण में bar तरह वर्ग चर के रूप में अन्य तरीकों के अंदर उदाहरण चर को परिभाषित पसंद नहीं है।

फिर से, व्यक्तिगत रूप से, मैं शीर्ष पर देखकर अपनी कक्षा के प्रत्येक सदस्य को देखना पसंद करता हूं। चाहे वह एक क्लास वैरिएबल है जिसे आप एक आवृत्ति चर (कुछ जो मैं आमतौर पर नहीं करता) या __init__ में परिभाषित एक आवृत्ति चर के रूप में उपयोग करता हूं, यह कहना आसान है कि पहले खंड का निरीक्षण करके कक्षा में क्या परिभाषित किया गया है और परिभाषित नहीं किया गया है कक्षा परिभाषा का।

आप एक वर्ग के सदस्य (यानी के रूप में एक चर का उपयोग करने की जरूरत नहीं होगी। आप केवल यह वहाँ परिभाषित कर रहे हैं __init__ विधि में self.variable = val लेखन से बचने के लिए, तो मैं यह को दूर करने में होगा। आप का उपयोग करने की आवश्यकता हो सकती हैं यह एक वर्ग चर के रूप में है, तो क्या आप bar साथ हैं मेरी किताब में ठीक है।

यह आपको वर्ग लिखने की मेरी पसंदीदा तरीका होगा।

class Test1: 

    def __init__(self): 
     self.foo = None 
     self.bar = 10 

    def display(self,foo): 
     self.foo=foo 
     print "foo : ",self.foo #80 

    def display1(self): 
     print "bar: ", self.bar #10 
     print "again foo: ", self.foo #80 
संबंधित मुद्दे