नई शैली कक्षाओं (डिफ़ॉल्ट
3.x
) और
2.x
में वस्तु से विरासत में मिली विशेषता अवरोधन तरीकों
__getattr__
और
__getattribute__
are no longer called for built-in operations उदाहरणों में से दुंदर अतिभारित तरीकों पर और इसके बजाय खोज वर्ग में शुरू होता है में
।
इसके पीछे तर्क, मेटा क्लास की उपस्थिति से पेश की गई तकनीकीता शामिल है।
क्योंकि वर्ग मेटाक्लास के उदाहरण हैं और चूंकि मेटाक्लास, कक्षाओं पर कार्य करने वाले कुछ संचालन को परिभाषित कर सकता है, कक्षा को छोड़कर (जिसे इस मामले में instance
माना जा सकता है) समझ में आता है; आपको मेटाक्लास में परिभाषित विधि का आह्वान करने की आवश्यकता है जिसे कक्षाओं को संसाधित करने के लिए परिभाषित किया गया है (cls
पहले तर्क के रूप में)। यदि इंस्टेंस लुक-अप का उपयोग किया गया था, तो लुक-अप क्लास विधि का उपयोग करेगा जिसे उस वर्ग के उदाहरणों के लिए परिभाषित किया गया है (self
)।
एक और (विवादित कारण) शामिल है अनुकूलन: चूंकि उदाहरणों पर निर्मित आपरेशन आमतौर पर बहुत अक्सर लागू कर रहे हैं, लंघन उदाहरण देखने-अप पूरी तरह और वर्ग तक जाया जा सकता हमें कुछ समय बचाता है।[स्रोत लुट्ज़, सीखना अजगर, 5 वें संस्करण]
मुख्य क्षेत्र जहां इस जाता है जब प्रॉक्सी वस्तुओं है कि इरादे कॉल अग्रेषित करने के साथ __getattr__
और __getattribute__
ओवरलोड एम्बेडेड आंतरिक बनाने असुविधा का हो सकता है वस्तु। चूंकि अंतर्निहित आमंत्रण पूरी तरह से उदाहरण को छोड़ देगा, इसलिए वे पकड़े नहीं जाएंगे और प्रभाव के रूप में एम्बेडेड ऑब्जेक्ट को अग्रेषित नहीं किया जाएगा।
इसके लिए एक आसान, लेकिन थकाऊ, काम-आसपास वास्तव में उन सभी डंडर्स को अधिभारित करना है जिन्हें आप प्रॉक्सी ऑब्जेक्ट में अवरुद्ध करना चाहते हैं। फिर इन ओवरलोडेड डंडर्स में आप आवश्यकतानुसार आंतरिक ऑब्जेक्ट को कॉल का प्रतिनिधि बना सकते हैं।
सबसे आसान काम के आसपास मैं setattr
साथ वर्ग Foo
पर विशेषता सेट कर रहा है के बारे में सोच सकते हैं: एक वर्ग
setattr(Foo, '__call__', lambda *args: print(args))
f(1, 2, 3)
(<__main__.Foo object at 0x7f40640faa90>, 1, 2, 3)
परिभाषित करने के लिए एक प्रति उदाहरण '__call__' कार्यान्वयन मैं वर्तमान में उपयोग कर रहा हूँ -लेवल '__call__' कि एक नियमित सदस्य के लिए आगे। हालांकि एक बदसूरत समाधान लगता है ... – 6502
@ 6502: यह अनुशंसित काम है। यदि आपको वास्तव में एक प्रति-उदाहरण कॉल करने योग्य को प्रतिनिधि करने की आवश्यकता है, तो कक्षा-स्तर '__call__' में स्पष्ट रूप से ऐसा करने का ऐसा करने का सबसे अच्छा तरीका है। –
@MartijnPieters प्रॉक्सी के अंदर एक पूर्णांक ऑब्जेक्ट स्टोर में सभी ऑपरेटरों ('__add__',' __rtruediv__', आदि) को आगे बढ़ाने के लिए एक काम क्या होगा? यदि संभव हो तो मैं मैन्युअल रूप से सभी विधियों को लागू नहीं करना चाहता हूं। – danijar