2012-12-03 20 views
6

Django स्रोत कोड पढ़ना मैं this फ़ंक्शन पर आया था। यह block टैग के लिए कार्यान्वयन है।कक्षा * बाहर * से "निजी" पायथन विशेषता क्यों सेट करें?

मुझे क्या अच्छा लगता है कि वे एक चर दो प्रमुख अंडरस्कोर (__loaded_blocks) के साथ से बाहर parser वर्ग उदाहरण स्थापित कर रहे हैं (पार्सर Parser class का एक उदाहरण है) है। Django स्रोत कोड में एक त्वरित grep से पता चलता है कि स्ट्रिंग loaded_blocks केवल यहां होती है।

अब मैंने पहले कभी भी पाइथन नाम-मैंगलिंग सुविधा का उपयोग नहीं किया है, लेकिन यह parser की विशेषता को अपने आप से छुपाएगा! parser विधि से इस विशेषता को पढ़ने के लिए आपको getattr(self, "__loaded_blocks") का सहारा लेना होगा।

मैं सही सोच में हूँ यह सिर्फ एक अनपेक्षित और अप्रयुक्त पक्ष चुना विशेषता नाम का असर है? या क्या इसका गहरा उद्देश्य है?

आम तौर पर, आप ऐसा क्यों करना चाहते हैं?

संपादित करें: स्पष्ट करने के लिए, मैं पूरी तरह से पता है कि जब तक आप parser की एक विधि से __loaded_blocks विशेषता का उपयोग करने की कोशिश मत करो के रूप में, यह सिर्फ किसी भी अन्य विशेषता की तरह काम करेगा हूँ, और यह है कि वास्तव में एक उलझन में विशेषता नहीं है।

+2

कोई प्रयोजन के उपभोक्ता के लिए "निजी" के रूप में इस के निशान, Django सिर्फ बदसूरत कोड है। – Keith

उत्तर

3

मुझे नहीं लगता कि नाम mangling को होगा जब आप से एक उदाहरण

में कोई प्रॉपर्टी __ उपसर्ग के साथ जोड़ सकता हूँ docs:

निजी नाम mangling: जब एक पहचानकर्ता है कि टेक्स्ट रूप में होता है कक्षा परिभाषा दो या दो से अधिक अंडरस्कोर वर्णों से शुरू होती है और दो या अधिक अंडरस्कोर में समाप्त नहीं होती है, इसे उस श्रेणी का निजी नाम माना जाता है। उनके नाम कोड उत्पन्न होने से पहले निजी नाम लंबे प्रारूप में परिवर्तित हो जाते हैं। परिवर्तन नाम के सामने वर्ग का नाम डाला गया है, जिसमें अग्रणी अंडरस्कोर हटा दिए गए हैं, और कक्षा नाम के सामने डाला गया एक एकल अंडरस्कोर है। उदाहरण के लिए, हैम नामक कक्षा में होने वाले पहचानकर्ता __spam हैम _spam में परिवर्तित हो जाएगा। यह परिवर्तन सिंटैक्टिकल संदर्भ से स्वतंत्र है जिसमें पहचानकर्ता का उपयोग किया जाता है। यदि परिवर्तित नाम बहुत लंबा है (255 वर्णों से लंबा), कार्यान्वयन परिभाषित परिभाषा हो सकती है। यदि वर्ग का नाम केवल अंडरस्कोर होता है, तो कोई परिवर्तन नहीं किया जाता है।

class Test: 
    pass 

test = Test() 
test.__hello = 'hii'  
test.__hello # hiii 

हालांकि नाम घायल नहीं है यह अभी भी कोड

+0

ओह, मुझे यह एहसास है। लेकिन अगर आपने 'टेस्ट' में एक विधि बनाई है जिसे सेट करने के बाद '__hello' विशेषता मुद्रित की गई है, तो यह सक्षम नहीं होगा, क्योंकि वास्तव में यह' _Test__hello' विशेषता मुद्रित करने का प्रयास करेगा। जैसा कि मैंने कहा, इस तरह के एक विधि को बाहरी सेट '__hello' विशेषता मुद्रित करने के लिए 'getattr' का उपयोग करना होगा। –

+0

@lazyr ओओ हाँ मैं देख रहा हूँ कि अब आप क्या कह रहे हैं! वे इसे एक विधि से नहीं पढ़ रहे हैं और यदि उन्होंने शर्त लगाई तो वे डबल अंडरस्कोर के साथ एक चर नहीं बनाया होगा ... – dm03514

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