पायथन नाम मैनबलिंग


109

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

क्या वही धारण अजगर के लिए सही है? क्या मुझे पहली बार में हर चीज पर दो प्रमुख अंडरस्कोर का उपयोग करना चाहिए, और केवल उन्हें कम छिपाना चाहिए (केवल एक अंडरस्कोर) जैसा कि मुझे उनकी आवश्यकता है?

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

यहाँ एक टिप्पणी है जो मैंने जेबरनार्डो के उत्तर पर छोड़ दी है । यह बताता है कि मैंने यह सवाल क्यों पूछा और यह भी जानना चाहूंगा कि पायथन अन्य भाषाओं से अलग क्यों है:

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

जवाबों:


182

जब संदेह हो, तो इसे "सार्वजनिक" छोड़ दें - मेरा मतलब है, अपनी विशेषता के नाम को अस्पष्ट करने के लिए कुछ भी न जोड़ें। यदि आपके पास कुछ आंतरिक मूल्य के साथ एक वर्ग है, तो इसके बारे में परेशान न करें। लिखने के बजाय:

class Stack(object):

    def __init__(self):
        self.__storage = [] # Too uptight

    def push(self, value):
        self.__storage.append(value)

इसे डिफ़ॉल्ट रूप से लिखें:

class Stack(object):

    def __init__(self):
        self.storage = [] # No mangling

    def push(self, value):
        self.storage.append(value)

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

यदि आप वास्तव में संदेश भेजना चाहते हैं तो "यह स्पर्श नहीं कर सकता!" अपने उपयोगकर्ताओं के लिए, सामान्य तरीका यह है कि एक अंडरस्कोर के साथ चर को पूर्ववर्ती करें । यह सिर्फ एक सम्मेलन है, लेकिन लोग इसे समझते हैं और इस तरह के सामान से निपटने पर दोहरा ध्यान रखते हैं:

class Stack(object):

    def __init__(self):
        self._storage = [] # This is ok but pythonistas use it to be relaxed about it

    def push(self, value):
        self._storage.append(value)

यह संपत्ति के नाम और विशेषता नामों के बीच संघर्ष से बचने के लिए भी उपयोगी हो सकता है:

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self._age = age if age >= 0 else 0

     @property
     def age(self):
         return self._age

     @age.setter
     def age(self, age):
         if age >= 0:
             self._age = age
         else:
             self._age  = 0

डबल अंडरस्कोर के बारे में क्या? खैर, डबल अंडरस्कोर जादू का उपयोग मुख्य रूप से विधियों के आकस्मिक अतिभार से बचने और सुपरक्लेसेस की विशेषताओं के साथ नाम संघर्ष के लिए किया जाता है । यह काफी उपयोगी हो सकता है यदि आप एक वर्ग लिखते हैं जिसे कई बार बढ़ाया जाना अपेक्षित है।

यदि आप इसे अन्य उद्देश्यों के लिए उपयोग करना चाहते हैं, तो आप कर सकते हैं, लेकिन यह न तो सामान्य है और न ही अनुशंसित है।

संपादित करें : ऐसा क्यों है? ठीक है, सामान्य पायथन शैली चीजों को निजी बनाने पर जोर नहीं देती है - इसके विपरीत! इसके कई कारण हैं - उनमें से अधिकांश विवादास्पद हैं ... आइए हम उनमें से कुछ को देखते हैं।

अजगर में गुण होते हैं

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

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

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

person.age = age;

अपने कोड में, हम कहते हैं,

person.setAge(age);

setAge() किया जा रहा है:

public void setAge(int age) {
    if (age >= 0) {
        this.age = age;
    } else {
        this.age = 0;
    }
}

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

हालाँकि, आपको इसे पायथन में करने की आवश्यकता नहीं है, क्योंकि पायथन में गुण हैं। यदि आपके पास यह वर्ग है:

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self.age = age

और फिर आप उम्र को मान्य करने का निर्णय लेते हैं, आपको person.age = ageअपने कोड के टुकड़ों को बदलने की आवश्यकता नहीं है । बस एक संपत्ति जोड़ें (जैसा कि नीचे दिखाया गया है)

 class Person(object):
     def __init__(self, name, age):
         self.name = name
         self._age = age if age >= 0 else 0

     @property
     def age(self):
         return self._age

     @age.setter
     def age(self, age):
         if age >= 0:
             self._age = age
         else:
             self._age  = 0

यदि आप इसे कर सकते हैं और अभी भी उपयोग कर सकते हैं person.age = age, तो आप निजी फ़ील्ड और गेटर्स और सेटर क्यों जोड़ेंगे?

(यह भी देखें कि पायथन जावा नहीं है और यह लेख गेटर्स और सेटर का उपयोग करने के नुकसान के बारे में है ।)

सब कुछ वैसे भी दिखाई देता है - और छिपाने की कोशिश करना आपके काम को जटिल बनाता है

यहां तक ​​कि उन भाषाओं में जहां निजी विशेषताएं हैं, आप उन्हें किसी प्रकार के प्रतिबिंब / आत्मनिरीक्षण पुस्तकालय के माध्यम से एक्सेस कर सकते हैं। और लोग इसे बहुत कुछ करते हैं, रूपरेखा में और तत्काल जरूरतों को हल करने के लिए। समस्या यह है कि आत्मनिरीक्षण पुस्तकालय केवल सार्वजनिक विशेषताओं के साथ कर सकने का एक कठिन तरीका है।

चूँकि पायथन एक बहुत ही गतिशील भाषा है, इसलिए इस बोझ को अपनी कक्षाओं में जोड़ना अभी ठीक नहीं है।

समस्या को देखना संभव नहीं है - यह देखने के लिए आवश्यक है

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

अब, यदि आपने अपनी कक्षा को इस तरह से लिखा है, तो आप कार्यान्वयन विवरण के बारे में सोचने के बिना इसका उपयोग कर सकते हैं, यदि आप किसी कारण से कक्षा के अंदर देखना चाहते हैं तो कोई समस्या नहीं है । मुद्दा यह है: आपका एपीआई अच्छा होना चाहिए और बाकी विवरण है।

गुइडो ने ऐसा कहा

खैर, यह विवादास्पद नहीं है: उन्होंने ऐसा कहा, वास्तव में । ("किमोनो खोलें" के लिए देखें)

यह संस्कृति है

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

चूंकि पहले से ही यह संस्कृति है, इसलिए आपको इसका पालन करने की सलाह दी जाती है। अन्यथा, __जब आप स्टैक ओवरस्ट्रीम में एक प्रश्न पूछेंगे , तो पायथन प्रोग्रामर आपको अपने कोड से हटाने के लिए कहेंगे।


1. इनकैप्सुलेशन वर्ग के आक्रमणकारियों की रक्षा के लिए है। बाहरी दुनिया से अनावश्यक विवरण न छिपाएं क्योंकि यह एक झुंझलाहट होगी। 2. "बिंदु यह है: आपका एपीआई अच्छा होना चाहिए और बाकी विवरण है।" यह सच है। और सार्वजनिक विशेषताएँ आपके एपीआई का हिस्सा हैं। इसके अलावा, कभी-कभी सार्वजनिक बसंत उपयुक्त होते हैं (आपके वर्ग के आक्रमणकारियों के विषय में) और कभी-कभी वे नहीं होते हैं। एक एपीआई जिसमें सार्वजनिक बसने वाले होते हैं, जिन्हें सार्वजनिक नहीं होना चाहिए (आक्रमणकारियों के उल्लंघन का जोखिम) एक बुरा एपीआई है। इसका मतलब है कि आपको प्रत्येक सेटर की दृश्यता के बारे में वैसे भी सोचना होगा और 'डिफ़ॉल्ट' होना कम अर्थ रखता है।
बृहस्पति

21

पहला - नाम मैनलिंग क्या है?

जब आप एक वर्ग परिभाषा और उपयोग करते हैं __any_nameया __any_name_, अर्थात, दो (या अधिक) अग्रणी अंडरस्कोर और अधिकतम एक अनुरेखक अंडरस्कोर में नाम मैनलिंग का उपयोग किया जाता है ।

class Demo:
    __any_name = "__any_name"
    __any_other_name_ = "__any_other_name_"

और अब:

>>> [n for n in dir(Demo) if 'any' in n]
['_Demo__any_name', '_Demo__any_other_name_']
>>> Demo._Demo__any_name
'__any_name'
>>> Demo._Demo__any_other_name_
'__any_other_name_'

जब संदेह हो, तो क्या करें?

अवलंबी उपयोग उपवर्गों को एक विशेषता का उपयोग करने से रोकने के लिए है जो वर्ग उपयोग करता है।

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

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

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

आपको इसके बारे में पता होना चाहिए ताकि आप इसे देखते समय इसे जान सकें।

पीईपी 8

PEP 8 , पायथन स्टैंडर्ड लाइब्रेरी स्टाइल गाइड, वर्तमान में कहता है (संक्षिप्त):

के उपयोग को लेकर कुछ विवाद है __names

यदि आपकी कक्षा को उपवर्गित करने का इरादा है, और आपके पास विशेषताएँ हैं कि आप उपवर्गों का उपयोग नहीं करना चाहते हैं, तो उन्हें डबल अग्रणी अंडरस्कोर और कोई ट्रेलिंग अंडरस्कोर के साथ नामकरण पर विचार करें।

  1. ध्यान दें कि मैंगल्ड नाम में केवल साधारण वर्ग के नाम का उपयोग किया जाता है, इसलिए यदि कोई उपवर्ग एक ही वर्ग नाम और विशेषता नाम दोनों को चुनता है, तो भी आप नाम टकराव प्राप्त कर सकते हैं।

  2. नाम मैनलिंग कुछ उपयोग कर सकते हैं, जैसे डिबगिंग और __getattr__(), कम सुविधाजनक। हालाँकि, नाम का उपयोग करने वाला एल्गोरिथ्म अच्छी तरह से प्रलेखित है और मैन्युअल रूप से प्रदर्शन करने में आसान है।

  3. हर किसी को नाम मेंशनिंग पसंद नहीं है। उन्नत कॉलर्स द्वारा संभावित उपयोग के साथ आकस्मिक नाम के टकराव से बचने की आवश्यकता को संतुलित करने का प्रयास करें।

यह कैसे काम करता है?

यदि आप एक वर्ग परिभाषा में दो अंडरस्कोर (डबल-अंडरस्कोर समाप्त किए बिना) प्रीपेंड करते हैं, तो नाम को जोड़ दिया जाएगा, और क्लास के नाम के बाद एक अंडरस्कोर वस्तु पर पूर्व निर्धारित किया जाएगा:

>>> class Foo(object):
...     __foobar = None
...     _foobaz = None
...     __fooquux__ = None
... 
>>> [name for name in dir(Foo) if 'foo' in name]
['_Foo__foobar', '__fooquux__', '_foobaz']

ध्यान दें कि जब वर्ग परिभाषा को पार्स किया जाता है तो केवल नाम ही मंगवाए जाएंगे:

>>> Foo.__test = None
>>> Foo.__test
>>> Foo._Foo__test
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute '_Foo__test'

इसके अलावा, पायथन के लिए नए लोगों को कभी-कभी यह समझने में परेशानी होती है कि क्या हो रहा है जब वे मैन्युअल रूप से एक नाम का उपयोग नहीं कर सकते हैं जो वे एक वर्ग परिभाषा में परिभाषित देखते हैं। यह इसके खिलाफ एक मजबूत कारण नहीं है, लेकिन अगर आपके पास सीखने वाले दर्शक हैं, तो यह विचार करने के लिए कुछ है।

एक अंडरस्कोर?

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

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

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


15

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

एक बेहतर समाधान वह मार्ग है जिसे पायथन प्रोत्साहित करता है: आपकी कक्षाओं और चर को अच्छी तरह से प्रलेखित किया जाना चाहिए, और उनका व्यवहार स्पष्ट होना चाहिए। स्रोत उपलब्ध होना चाहिए। कोड लिखने के लिए यह कहीं अधिक एक्स्टेंसिबल और विश्वसनीय तरीका है।

पायथन में मेरी रणनीति यह है:

  1. बस लानत की बात लिखें, इस बारे में कोई धारणा न बनाएं कि आपके डेटा को कैसे संरक्षित किया जाना चाहिए। यह मानता है कि आप अपनी समस्याओं के लिए आदर्श इंटरफेस बनाने के लिए लिखते हैं।
  2. सामान के लिए एक प्रमुख अंडरस्कोर का उपयोग करें जो संभवतः बाहरी रूप से उपयोग नहीं किया जाएगा, और सामान्य "क्लाइंट कोड" इंटरफ़ेस का हिस्सा नहीं है।
  3. डबल अंडरस्कोर का उपयोग केवल उन चीजों के लिए करें जो विशुद्ध रूप से कक्षा के अंदर हैं, या गलती से उजागर होने पर काफी नुकसान पहुंचाएंगे।

इन सबसे ऊपर, यह स्पष्ट होना चाहिए कि सब कुछ क्या करता है। यदि कोई अन्य व्यक्ति इसका उपयोग कर रहा होगा तो उसे दस्तावेज दें। यदि आप चाहते हैं कि यह एक साल के समय में उपयोगी हो, तो इसे दस्तावेज़ करें।

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


9

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

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

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


6

इस बारे में पहले से ही कई अच्छे जवाब हैं, लेकिन मैं एक और पेशकश करने जा रहा हूं। यह आंशिक रूप से उन लोगों की प्रतिक्रिया भी है जो यह कहते रहते हैं कि डबल अंडरस्कोर निजी नहीं है (यह वास्तव में है)।

यदि आप जावा / सी # को देखते हैं, तो दोनों के निजी / संरक्षित / सार्वजनिक हैं। ये सभी संकलन-समय के निर्माण हैं । उन्हें केवल संकलन के समय लागू किया जाता है। यदि आप जावा / सी # में प्रतिबिंब का उपयोग करते हैं, तो आप आसानी से निजी पद्धति का उपयोग कर सकते हैं।

अब हर बार जब आप पायथन में एक फ़ंक्शन कहते हैं, तो आप स्वाभाविक रूप से प्रतिबिंब का उपयोग कर रहे हैं। कोड के ये टुकड़े पायथन में समान हैं।

lst = []
lst.append(1)
getattr(lst, 'append')(1)

"डॉट" सिंटैक्स कोड के बाद के टुकड़े के लिए केवल वाक्यविन्यास चीनी है। ज्यादातर क्योंकि गेटअटर का उपयोग केवल एक फ़ंक्शन कॉल के साथ पहले से ही बदसूरत है। बस वहीं से बिगड़ जाती है।

तो उस के साथ, प्राइवेट का जावा / सी # संस्करण नहीं हो सकता है, क्योंकि पायथन कोड को संकलित नहीं करता है। जावा और C # जाँच नहीं कर सकता है कि कोई फ़ंक्शन रनटाइम पर निजी या सार्वजनिक है, क्योंकि वह जानकारी चली गई है (और यह पता नहीं है कि फ़ंक्शन कहाँ से कॉल किया जा रहा है)।

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

डिस्क्लेमर: मैंने पायथन विकास के किसी भी व्यक्ति को कभी भी ऐसा कुछ नहीं सुना है। "निजी" की कमी का वास्तविक कारण सांस्कृतिक है, लेकिन आप यह भी देखेंगे कि अधिकांश स्क्रिप्टिंग / व्याख्या की गई भाषाओं में कोई निजी नहीं है। एक कड़ाई से लागू निजी संकलन समय को छोड़कर किसी भी चीज में व्यावहारिक नहीं है।


4

पहला: आप अपना डेटा क्यों छिपाना चाहते हैं? क्यों यह इतना महत्वपूर्ण है?

अधिकांश समय आप वास्तव में ऐसा नहीं करना चाहते हैं लेकिन आप ऐसा इसलिए करते हैं क्योंकि अन्य लोग कर रहे हैं।

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

यही तरीका है कि हम जीते हैं और हम उसी के साथ ठीक हैं।

दो अंडरस्कोर का उपयोग आपकी कक्षा को उपवर्ग में इतना खराब कर देगा कि आप उस तरह से काम भी नहीं करना चाहेंगे।


2
आपने कारण को छोड़ दिया है कि अंडरक्लेशिंग के लिए डबल अंडरस्कोर खराब है ... इससे आपका उत्तर बेहतर होगा।
मैट जॉइनर

2
यह देखते हुए कि डबल अंडरस्कोर वास्तव में केवल उपवर्गों के साथ नाम टकराव को रोकने के लिए हैं (कहने के तरीके के रूप में, "हैंड्स ऑफ," सबक्लासर्स के लिए), मैं यह नहीं देखता कि नामकरण कैसे समस्या पैदा करता है।
हारून हॉल

4

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

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


3

निम्नलिखित कोड स्निपेट सभी अलग-अलग मामलों की व्याख्या करेगा:

  • दो प्रमुख अंडरस्कोर (__a)
  • एकल प्रमुख अंडरस्कोर (_a)
  • कोई अंडरस्कोर (ए) नहीं

    class Test:
    
    def __init__(self):
        self.__a = 'test1'
        self._a = 'test2'
        self.a = 'test3'
    
    def change_value(self,value):
        self.__a = value
        return self.__a

टेस्ट ऑब्जेक्ट की सभी मान्य विशेषताओं को प्रिंट करना

testObj1 = Test()
valid_attributes = dir(testObj1)
print valid_attributes

['_Test__a', '__doc__', '__init__', '__module__', '_a', 'a', 
'change_value']

यहाँ, आप देख सकते हैं कि __a का नाम बदलकर _Test__a कर दिया गया है ताकि किसी भी उपवर्ग द्वारा इस चर को ओवरराइड करने से रोका जा सके। इस अवधारणा को अजगर में "नाम मंगलिंग" के रूप में जाना जाता है। आप इसे इस तरह एक्सेस कर सकते हैं:

testObj2 = Test()
print testObj2._Test__a

test1

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

testObj3 = Test()
print testObj3._a

test2

एक चर एक सार्वजनिक वर्ग चर की तरह कहीं से भी पहुँचा जा सकता है।

testObj4 = Test()
print testObj4.a

test3

आशा है कि उत्तर ने आपकी मदद की :)


2

पहली नज़र में यह अन्य भाषाओं के लिए समान होना चाहिए ("अन्य" के तहत मेरा मतलब जावा या सी ++ है), लेकिन यह नहीं है।

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

इसलिए, मैं आपको "निजी" सदस्यों के लिए डिफ़ॉल्ट रूप से एकल अंडरस्कोर का उपयोग करने की सलाह दूंगा।


"निजी" के लिए डबल अंडरस्कोर और "संरक्षित" के लिए सिंगल अंडरस्कोर का उपयोग करें। आमतौर पर, लोग हर चीज के लिए सिंगल अंडरस्कोर का इस्तेमाल करते हैं (डबल अंडरस्कोर निजता को लागू करने में मदद करेगा, जो आमतौर पर पायथन स्टाइल के खिलाफ है)।
जोनाथन स्टर्नबर्ग

1
लेकिन क्या यह निजी के समान दो अंडरस्कोर और एक अंडरस्कोर संरक्षित के समान नहीं है? सिर्फ "निजी" से ही क्यों न शुरू किया जाए?
पॉल मंटा

@Paul नहीं, यह नहीं है। पायथन में कोई निजी नहीं है और आपको इसे हासिल करने की कोशिश नहीं करनी चाहिए।
रोमन बोडनार्चुक

@Roman वैचारिक रूप से ... 'निजी' के आसपास के उद्धरण नोटिस।
पॉल मंटा

1

"अगर इस बारे में संदेह है कि क्या एक चर निजी या संरक्षित होना चाहिए, तो निजी के साथ जाना बेहतर है।" - हां, पाइथन में वही है।

यहां कुछ जवाब 'सम्मेलनों' के बारे में कहते हैं, लेकिन उन सम्मेलनों के लिंक नहीं देते हैं। पायथन, पीईपी 8 राज्यों के लिए आधिकारिक गाइड स्पष्ट रूप से है:

यदि संदेह है, तो गैर-सार्वजनिक चुनें; सार्वजनिक विशेषता को गैर-सार्वजनिक बनाने के बजाय इसे बाद में सार्वजनिक करना अधिक आसान है।

सार्वजनिक और निजी, और पायथन में नाम के बीच अंतर को अन्य उत्तरों में माना गया है। उसी लिंक से,

हम यहां "निजी" शब्द का उपयोग नहीं करते हैं, क्योंकि पायथन में कोई भी विशेषता वास्तव में निजी नहीं है (आमतौर पर बिना काम के अनावश्यक राशि)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.