python क्या पाइथन कक्षाओं में "निजी" चर है?




class private (8)

थ्रेड को "पुनरुत्थान" के लिए खेद है, लेकिन मुझे आशा है कि इससे किसी की मदद मिलेगी:

पायथन 3 में यदि आप क्लास विशेषताओं को "एन्सेप्लेट" करना चाहते हैं, जैसे कि जावा में, आप बस इसी तरह की चीज कर सकते हैं:

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

इसे तुरंत करने के लिए:

ss = Simple("lol")
ss.show()

ध्यान दें कि: print(ss.__s) एक त्रुटि फेंक देगा।

अभ्यास में, पायथन 3 वैश्विक विशेषता नाम को खराब कर देगा। जावा में जैसे "निजी" विशेषता की तरह इसे चालू करना। विशेषता का नाम अभी भी वैश्विक है, लेकिन एक अप्राप्य तरीके से, अन्य भाषाओं में एक निजी विशेषता की तरह।

लेकिन इससे डरो मत। कोई फर्क नहीं पड़ता कि। यह नौकरी भी करता है। ;)

मैं जावा दुनिया से आ रहा हूं और ब्रूस एक्सल्स के पायथन 3 पैटर्न, रेसिपी और इडियम्स पढ़ रहा हूं।

कक्षाओं के बारे में पढ़ते समय, यह कहता है कि पायथन में इंस्टेंस चर घोषित करने की कोई आवश्यकता नहीं है। आप बस उन्हें कन्स्ट्रक्टर में इस्तेमाल करते हैं, और उछालते हैं, वे वहां हैं।

तो उदाहरण के लिए:

class Simple:
    def __init__(self1, str):
        print("inside the simple constructor")
        self1.s = str
    def show(self1):
        print(self1.s)
    def showMsg (self, msg):
        print (msg + ':', self.show())

यदि यह सत्य है, तो क्लास Simple का कोई भी ऑब्जेक्ट क्लास के बाहर परिवर्तनीय s के मान को बदल सकता है।

उदाहरण के लिए:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

जावा में, हमें सार्वजनिक / निजी / संरक्षित चर के बारे में सिखाया गया है। वे कीवर्ड समझ में आते हैं क्योंकि कभी-कभी आप कक्षा में चर चाहते हैं जिसके लिए कक्षा के बाहर कोई भी पहुंच नहीं लेता है।

पायथन में इसकी आवश्यकता क्यों नहीं है?


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

उस पर और अधिक के लिए here देखें।

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


"जावा में, हमें सार्वजनिक / निजी / संरक्षित चर के बारे में सिखाया गया है"

"पाइथन में इसकी आवश्यकता क्यों नहीं है?"

इसी कारण से जावा में इसकी आवश्यकता नहीं है।

आप उपयोग करने के लिए स्वतंत्र हैं - या private और protected उपयोग नहीं करते हैं।

एक पायथन और जावा प्रोग्रामर के रूप में, मैंने पाया है कि private और protected बहुत ही महत्वपूर्ण डिजाइन अवधारणाएं हैं। लेकिन एक व्यावहारिक मामले के रूप में, जावा और पायथन की हजारों लाइनों में, मैंने वास्तव में कभी भी private या protected उपयोग नहीं किया protected

क्यों नहीं?

मेरा सवाल है "किससे संरक्षित?"

मेरी टीम पर अन्य प्रोग्रामर? उनके पास स्रोत है। संरक्षित मतलब क्या है जब वे इसे बदल सकते हैं?

अन्य टीमों पर अन्य प्रोग्रामर? वे एक ही कंपनी के लिए काम करते हैं। वे कर सकते हैं - एक फोन कॉल के साथ - स्रोत प्राप्त करें।

ग्राहकों को? यह काम-के-किराए पर प्रोग्रामिंग (आमतौर पर) है। ग्राहक (आमतौर पर) कोड का मालिक है।

तो, कौन - ठीक है - क्या मैं इसे से बचा रहा हूं?

सही। स्किज़ोफ्रेनिक सोसायपाथ जिन्होंने एपीआई टिप्पणी ब्लॉक पढ़ने से इनकार कर दिया।


पाइथन में निजी चर हैक कम या ज्यादा है: दुभाषिया जानबूझकर चर का नाम बदलता है।

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

अब, यदि आप वर्ग परिभाषा के बाहर __var तक पहुंचने का प्रयास करते हैं, तो यह असफल हो जाएगा:

 >>>x = A()
 >>>x.__var # this will return error: "A has no attribute __var"

 >>>x.printVar() # this gives back 123

लेकिन आप आसानी से इससे दूर हो सकते हैं:

 >>>x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

 >>>x._A__var = 456 # you now know the masked name of private variables
 >>>x.printVar() # this gives back 456

आप शायद जानते हैं कि x.printVar() => A.printVar(x) में विधियों को इस तरह से बुलाया जाता है: x.printVar() => A.printVar(x) , यदि A.printVar() x में कुछ फ़ील्ड तक पहुंच सकता है, तो इस क्षेत्र को A.printVar() बाहर भी पहुंचा जा सकता है A.printVar() ... आखिरकार, पुन: प्रयोज्यता के लिए कार्य बनाए जाते हैं, अंदर दिए गए बयानों को कोई विशेष शक्ति नहीं दी जाती है।

एक कंपाइलर शामिल होने पर गेम अलग होता है ( गोपनीयता एक कंपाइलर स्तर अवधारणा है )। यह अभिगम नियंत्रण संशोधक के साथ कक्षा परिभाषा के बारे में जानता है, इसलिए यह संकलित समय पर नियमों का पालन नहीं किया जा सकता है, तो यह त्रुटि हो सकती है


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


निजी और संरक्षित अवधारणाएं बहुत महत्वपूर्ण हैं। लेकिन पायथन - विकास के लिए उपलब्ध प्रतिबंधित संसाधनों के साथ प्रोटोटाइप और तेजी से विकास के लिए एक उपकरण, यही कारण है कि कुछ स्तरों में पाइथन में इतनी सख्तता नहीं होती है। आप वर्ग सदस्य में "__" का उपयोग कर सकते हैं, यह ठीक से काम करता है, लेकिन पर्याप्त अच्छा नहीं दिखता है - इस क्षेत्र में प्रत्येक पहुंच में इन वर्ण हैं।

साथ ही, आप देख सकते हैं कि पायथन ओओपी अवधारणा सही ओओपी अवधारणा के करीब बिल्कुल सही, स्माल्टॉक या रूबी नहीं है। यहां तक ​​कि सी # या जावा करीब हैं।

पायथन बहुत अच्छा उपकरण है। लेकिन यह ओओपी भाषा सरलीकृत है। Syntactically और अवधारणात्मक सरलीकृत। पायथन अस्तित्व का मुख्य लक्ष्य डेवलपर्स को उच्च अस्थिरता स्तर के साथ बहुत तेज़ तरीके से लिखने के लिए आसान पठनीय कोड लिखना है।


जैसा कि पहले उल्लेख किया गया है, आप इंगित कर सकते हैं कि एक चर या विधि अंडरस्कोर के साथ उपसर्ग करके निजी है। यदि आपको ऐसा नहीं लगता है कि यह पर्याप्त है, तो आप हमेशा property सजावट का उपयोग कर सकते property । यहां एक उदाहरण दिया गया है:

    class Foo:

        def __init__(self, bar):
            self._bar = bar

        @property
        def bar(self):
            """Getter for '_bar'."""
            return self._bar

इस तरह, किसी संदर्भ या bar जो संदर्भ bar वास्तव में चर के बजाए bar फ़ंक्शन के रिटर्न वैल्यू का संदर्भ bar है, और इसलिए इसे एक्सेस किया जा सकता है लेकिन बदला नहीं जा सकता है। हालांकि, अगर कोई वास्तव में चाहता था, तो वे बस _bar उपयोग कर सकते हैं और इसके लिए एक नया मान असाइन कर सकते हैं। किसी को ऐसे चर और विधियों तक पहुंचने से रोकने के लिए कोई निश्चित तरीका नहीं है जिसे आप छिपाना चाहते हैं, जैसा कि बार-बार कहा गया है। हालांकि, property का उपयोग करना सबसे स्पष्ट संदेश है जिसे आप भेज सकते हैं कि एक चर को संपादित नहीं किया जाना है। property को अधिक जटिल गेटर / सेटर / डिलीटर एक्सेस पथ के लिए भी इस्तेमाल किया जा सकता है, जैसा कि यहां बताया गया है: https://docs.python.org/3/library/functions.html#property


अंडरस्कोर सम्मेलन में निजी चरों की एक भिन्नता है।

In [5]: class test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:     

In [6]: x = test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'test' object has no attribute '__private_method'

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

@private decorators के उदाहरण हैं जो अवधारणा को अधिक बारीकी से लागू करते हैं, लेकिन वाईएमएमवी। तर्कसंगत रूप से कोई मेटा का उपयोग करने वाले वर्ग परिभाषा भी लिख सकता है





private