2012-10-13 5 views
8

शुद्धता के हित में किसी भी उदाहरण विशेषताओं को छोड़कर, अंतर्निहित विशेष विधि लुकअप आमतौर पर ऑब्जेक्ट के मेटाक्लास के __getattribute__() विधि को भी छोड़ देता है।पाइथन में __getattribute__ को कौन से विशेष तरीकों से गुजरता है?

ऐसे __hash__, __repr__ और __len__ रूप

The docs उल्लेख विशेष विधियों, और मैं अनुभव यह भी शामिल है पायथन 2.7 के लिए __iter__ से पता है।

an answer to a related question के शब्दों में:

"मैजिक __methods__() विशेष रूप से व्यवहार कर रहे हैं: वे आंतरिक रूप से करने के लिए आवंटित कर रहे हैं" उनके लुक-अप में तेजी लाने के प्रकार डेटा संरचना में स्लॉट ", और वे केवल इन में देखा जाता है स्लॉट्स। "

another question पर मेरा उत्तर सुधारने के लिए, मुझे यह जानने की ज़रूरत है: विशेष रूप से, हम किस तरीके से बात कर रहे हैं?

+0

स्लॉट को कौन सी विधियां सौंपी गई हैं? –

+7

मुझे लगता है कि सूचीबद्ध हर विधि [यहां] (http://docs.python.org/reference/datamodel.html#specialnames)। वैसे भी ध्यान रखें कि यह केवल तब लागू होता है जब आप "इसके वाक्यविन्यास" का उपयोग करके विधि को कॉल करते हैं। उदाहरण के लिए 'ए +5' '__getattribute__' को कॉल नहीं करेगा, जबकि' a .__ जोड़ें __ (5) '* * इसे कॉल करेगा। मूल रूप से '__getattribute__' को किसी भी विशेषता तक पहुंचने के लिए डॉट (' .') का उपयोग करने पर कॉल किया जाता है। – Bakuriu

+0

@ बाकुरी: बहुत जानकारीपूर्ण, धन्यवाद। – porgarmingduod

उत्तर

4

आप python3 object.__getattribute__ के लिए documentation, जिसमें कहा गया है में एक जवाब पा सकते हैं:

बिना शर्त बुलाया विशेषता लागू करने के लिए वर्ग की घटनाओं के लिए एक्सेस करता है। यदि कक्षा __getattr__() को भी परिभाषित करती है, तो बाद में __getattribute__() को तब तक नहीं बुलाया जाएगा जब तक कि यह स्पष्ट रूप से या एक विशेषता त्रुटि उठाता है। इस विधि को (गणना) विशेषता मान वापस करना चाहिए या एक विशेषता त्रुटि अपवाद बढ़ाएं। इस विधि में अनंत रिकर्सन से बचने के लिए क्रम में, इसके कार्यान्वयन को हमेशा उसी श्रेणी के साथ बेस क्लास विधि को कॉल करने के लिए तक पहुंचने के लिए किसी भी विशेषताओं की आवश्यकता होनी चाहिए, उदाहरण के लिए, ऑब्जेक्ट। __getattribute__(self, name)

नोट

जब वाक्य रचना या भाषा में निर्मित कार्यों के माध्यम से निहित मंगलाचरण का परिणाम के रूप में विशेष तरीकों को देख यह पद्धति अभी भी नजरअंदाज किया जा सकता है। विशेष विधि लुकअप देखें।

भी this पृष्ठ बताता है कि यह "मशीनरी" कैसे काम करता है। मूल रूप से __getattribute__ केवल तभी कॉल किया जाता है जब आप . (डॉट) ऑपरेटर (और hasattr के साथ एक विशेषता तक पहुंचते हैं क्योंकि ज़ागोरुलकिन ने बताया)।

ध्यान दें कि पेज को निर्दिष्ट नहीं करता जो विशेष तरीकों परोक्ष देखा जाता है, तो मैं समझना है कि उन सभी को (जो आप here मिल सकता है के लिए इस पकड़।

+0

क्या आपने वास्तव में जांच की थी? मैंने 2.7.9 पर जांच की और ऐसा लगता है कि दस्तावेज़ उस पर बिल्कुल सही नहीं हैं। –

1

2.7.9

नहीं किया जा सका चेक इन किया 'टी __getattribute__ करने के लिए कॉल बायपास करने के लिए किसी भी तरह से मिल जाए, जादुई तरीकों object या type पर पाए जाने वाले से किसी के साथ:

# Preparation step: did this from the console 
# magics = set(dir(object) + dir(type)) 
# got 38 names, for each of the names, wrote a.<that_name> to a file 
# Ended up with this: 

a.__module__ 
a.__base__ 
#... 

beginnin पर इस रखो उस फ़ाइल का जी, जिसे मैंने एक उचित पायथन मॉड्यूल में बदल दिया (asdf।> एक ही परिणाम - py)

global_counter = 0 

class Counter(object): 
    def __getattribute__(self, name): 
     # this will count how many times the method was called 
     global global_counter 
     global_counter += 1 
     return super(Counter, self).__getattribute__(name) 

a = Counter() 
# after this comes the list of 38 attribute accessess 
a.__module__ 
#... 
a.__repr__ 
#... 

print global_counter # you're not gonna like it... it printer 38 

तो मैं भी getattr और hasattr द्वारा उन नामों में से प्रत्येक के पाने की कोशिश की। __getattribute__ हर बार बुलाया गया था।

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

तो या तो ऐसा कुछ है जिसे मैं सही नहीं कर रहा हूं, या दस्तावेज़ झूठ बोल रहे हैं।

+1

यदि मुझे सही तरीके से याद है, तो मेरा प्रश्न 'repr (a)' के रूप में 'a .__ repr __()' के विपरीत था। यह थोड़ी देर के बाद से मैं इस सामान में था, लेकिन मुझे लगता है कि आपको गेटेट्रिब्यूट संस्करण मिलता है क्योंकि आप विशेषताओं को देखते हैं, जबकि अंतर्निहित विधियों के बारे में हम बात कर रहे हैं (वैश्विक 'repr', '__repr__' नहीं) बाईपास '__repr__' का अस्तित्व। – porgarmingduod

+0

जब भी इसे कॉल किया जाता है तो प्रिंट जारी करने के लिए '__getattribute__' ओवरराइड करें और फिर करें: 'काउंटर (' ए ') + काउंटर (' ए ')' और देखें कि यह कुछ भी प्रिंट नहीं करता है। चूंकि यह मानक नाम को छोड़कर 'काउंटर .__ dict __ [' __ add __ '] को सीधे देख रहा है और ऑप्टिमाइज़ेशन के नाम पर ऐसी कुछ मूर्खतापूर्ण चीज़ है। – justanr

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