पायथन में "निजी" (कार्यान्वयन) वर्ग


106

मैं दो भागों से बना एक छोटा अजगर मॉड्यूल कोडिंग कर रहा हूं:

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

सबसे पहले, मैंने इस कार्यान्वयन वर्ग को इसे उपयोग करने वाले फ़ंक्शन के अंदर परिभाषित करके "छिपाने" का फैसला किया, लेकिन अगर यह एक ही वर्ग के कई कार्यों का पुन: उपयोग करता है तो यह बाधा उत्पन्न करता है और इसका उपयोग नहीं किया जा सकता है।

तो, टिप्पणियों और डॉकस्ट्रिंग्स के अलावा, क्या एक वर्ग को "निजी" या "आंतरिक" के रूप में चिह्नित करने के लिए एक तंत्र है? मैं अंडरस्कोर तंत्र से अवगत हूं, लेकिन जैसा कि मैं समझता हूं कि यह केवल चर, फ़ंक्शन और विधियों के नाम पर लागू होता है।

जवाबों:


174

एकल अंडरस्कोर उपसर्ग का उपयोग करें:

class _Internal:
    ...

यह 'आंतरिक' प्रतीकों के लिए आधिकारिक पायथन सम्मेलन है; "मॉड्यूल आयात से *" अंडरस्कोर-उपसर्गित वस्तुओं को आयात नहीं करता है।

संपादित करें: एकल अंडरस्कोर सम्मेलन का संदर्भ


3
मुझे पता नहीं था कि अंडरस्कोर नियम कक्षाओं तक विस्तारित है। आयात करते समय मैं अपने नाम स्थान को अव्यवस्थित नहीं करना चाहता, इसलिए यह व्यवहार वह है जो मैं खोज रहा था। धन्यवाद!
ऑपरासी

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

11
python.org/dev/peps/pep-0008 - _single_leading_underscore: कमजोर "आंतरिक उपयोग" सूचक। उदाहरण के लिए "एम आयात *" उन वस्तुओं को आयात नहीं करता है जिनका नाम अंडरस्कोर से शुरू होता है। - आंतरिक उपयोग के लिए कक्षाओं में एक अग्रणी अंडरस्कोर है
माइल्स

2
एक प्रमुख अंडरस्कोर चीजों को आंतरिक के रूप में चिह्नित करने के लिए कन्वेंशन है, "इस के साथ गड़बड़ न करें," जबकि सभी को "एम आयात *" के साथ उपयोग किए जाने वाले मॉड्यूल के लिए अधिक है, जरूरी नहीं कि मॉड्यूल उपयोगकर्ताओं को स्पर्श न करें। वह वर्ग।
मैले

65

संक्षेप में:

  1. आप गोपनीयता लागू नहीं कर सकते । पायथन में कोई निजी वर्ग / विधियाँ / कार्य नहीं हैं। कम से कम, अन्य भाषाओं जैसे जावा में सख्त गोपनीयता नहीं।

  2. आप केवल गोपनीयता का संकेत / सुझाव दे सकते हैं । यह एक सम्मेलन का अनुसरण करता है। एक वर्ग / कार्य / विधि को निजी के रूप में चिह्नित करने के लिए अजगर सम्मेलन को एक _ (अंडरस्कोर) के साथ प्रस्तुत करना है। उदाहरण के लिए, def _myfunc()या class _MyClass:। आप दो अंडरस्कोर (जैसे:) के साथ विधि को पूर्वनिर्मित करके छद्म गोपनीयता भी बना सकते हैं __foo। आप सीधे विधि तक नहीं पहुँच सकते हैं, लेकिन आप अभी भी क्लासनेम (जैसे:) का उपयोग करके इसे एक विशेष उपसर्ग के माध्यम से कह सकते हैं _classname__foo। तो आप जो सबसे अच्छा कर सकते हैं, वह संकेत है / गोपनीयता का सुझाव देता है, इसे लागू नहीं करता है।

इस संबंध में पायल पर्ल की तरह है। पर्ल बुक से गोपनीयता के बारे में एक प्रसिद्ध पंक्ति को समझने के लिए, दर्शन यह है कि आपको लिविंग रूम से बाहर रहना चाहिए क्योंकि आपको आमंत्रित नहीं किया गया था, इसलिए नहीं कि यह शॉटगन के साथ बचाव है।

अधिक जानकारी के लिए:


# 1 के जवाब में, आप तरीकों की गोपनीयता को लागू कर सकते हैं। __Method (स्वयं) की तरह एक डबल अंडरस्कोर का उपयोग करना इसे कक्षा के बाहर दुर्गम बना देगा। लेकिन इसके चारों ओर एक रास्ता है जैसे इसे, फू () ._ Foo__method () कहकर पुकारना। मुझे लगता है कि यह सिर्फ कुछ और गूढ़ के लिए इसका नाम बदल देता है।
इवान फॉसमार्क

1
वह बोली सटीक है।
पॉल ड्रेपर

37

परिभाषित करें __all__, उन नामों की सूची जिन्हें आप निर्यात करना चाहते हैं ( प्रलेखन देखें )।

__all__ = ['public_class'] # don't add here the 'implementation_class'

10

एक पैटर्न जो मैं कभी-कभी उपयोग करता हूं वह यह है:

एक वर्ग को परिभाषित करें:

class x(object):
    def doThis(self):
        ...
    def doThat(self):
        ...

कक्षा का नाम लिखकर, कक्षा का एक उदाहरण बनाएँ:

x = x()

कार्यक्षमता को उजागर करने वाले प्रतीकों को परिभाषित करें:

doThis = x.doThis
doThat = x.doThat

उदाहरण स्वयं हटाएं:

del x

अब आपके पास एक मॉड्यूल है जो केवल आपके सार्वजनिक कार्यों को उजागर करता है।


2
"क्लास के नाम को अधिलेखित करना" के उद्देश्य / कार्य को समझने में एक मिनट लगा, लेकिन जब मैंने किया तो मुझे एक बड़ी मुस्कान मिली। निश्चित नहीं कि मैं इसका उपयोग कब करूंगा। :)
जैच यंग

क्या इस तकनीक का कोई नाम है?
बिश्वास मिश्र


4

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

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

इसके अलावा, सब कुछ सार्वजनिक होने के अपने स्वयं के भयानक भत्ते होते हैं, उदाहरण के लिए, आप बाहर से बहुत कुछ परीक्षण कर सकते हैं (जो आप वास्तव में C / C ++ निजी निर्माणों के साथ नहीं कर सकते हैं)।


4

"निजी" पहचानकर्ताओं के नामों को उपसर्ग करने के लिए दो अंडरस्कोर का उपयोग करें। एक मॉड्यूल में कक्षाओं के लिए, एकल अग्रणी अंडरस्कोर का उपयोग करें और उन्हें "मॉड्यूल आयात *" का उपयोग करके आयात नहीं किया जाएगा।

class _MyInternalClass:
    def __my_private_method:
        pass

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


दो _ का क्यों? एक पर्याप्त है।
S.Lott

एक एकल अंडरस्कोर "आयात" को वर्गों और कार्यों को आयात करने से रोकने के लिए पर्याप्त है। अजगर के नाम की मैनलिंग सुविधा को प्रेरित करने के लिए आपको दो अंडरस्कोर की आवश्यकता होती है। स्पष्ट होना चाहिए था; मैंने संपादित किया।
19

अब, अनुवर्ती। नामकरण क्यों? इसका संभावित लाभ क्या है?
एस.लॉट

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