2012-06-26 8 views
24

जब मैं कहता हूं "पायथन विशेषता लुकअप proccess" मेरा मतलब है: जब आप x.foo लिखते हैं तो क्या पाइथन करता है ??पाइथन विशेषता लुकअप प्रक्रिया कैसे काम करती है?

वेब मैं इस बारे में ज्यादा डॉक्स नहीं मिला था सर्च कर रहे हैं, सबसे अच्छा कागजात मैंने पाया में से एक के लिए निम्न चरण के लिए प्रक्रिया फिर से शुरू

  1. (आप पूरा लेख here देख सकते हैं), तो attrname है ऑब्जेक्टनाम के लिए एक विशेष (यानी पायथन-प्रदत्त) विशेषता, इसे वापस करें।
  2. ऑब्जेक्टनाम के लिए ऑब्जेक्टनाम .__ वर्ग __.__ dict__ की जांच करें। यदि यह मौजूद है और डेटा-डिस्क्रिप्टर है, तो वर्णनकर्ता परिणाम लौटाएं। उसी मामले के लिए objectname .__ class__ के सभी अड्डों को खोजें।
  3. ऑब्जेक्टनाम के लिए ऑब्जेक्टनाम .__ dict__ की जांच करें, और यदि मिले तो वापस लौटें। यदि ऑब्जेक्टनाम एक वर्ग है, तो इसके आधार भी खोजें। यदि यह एक वर्ग है और एक वर्णक इसके या उसके अड्डों में मौजूद है, तो वर्णनकर्ता परिणाम लौटाएं।
  4. ऑब्जेक्टनाम के लिए ऑब्जेक्टनाम .__ वर्ग __.__ dict__ की जांच करें। यदि यह मौजूद है और एक गैर-डेटा वर्णनकर्ता है, तो वर्णनकर्ता परिणाम लौटाएं। यदि यह मौजूद है, और एक वर्णक नहीं है, तो बस इसे वापस करें। यदि यह मौजूद है और डेटा डिस्क्रिप्टर है, तो हमें यहां नहीं होना चाहिए क्योंकि हम बिंदु 2 पर वापस आते थे। ऑब्जेक्टनाम के सभी अड्डों को खोजें .__ class__ उसी मामले के लिए।
  5. विशेषताएँ बढ़ाना त्रुटि।

सबसे पहले यह सही प्रतीत हो सकता है, लेकिन विशेषता लुकअप प्रक्रिया थोड़ी अधिक जटिल है, उदाहरण के लिए x.foo के लिए, यदि x कक्षा या उदाहरण है तो यह वही व्यवहार नहीं करता है।

मुझे कुछ नमूने मिल गए हैं जिन्हें इस तरह से समझाया नहीं जा सकता है।

class Meta(type): 
    def __getattribute__(self, name): 
     print("Metaclass getattribute invoked:", self) 
     return type.__getattribute__(self, name) 

    def __getattr__(self, item): 
     print('Metaclass getattr invoked: ', item) 
     return None 

class C(object, metaclass=Meta): 
    def __getattribute__(self, name): 
     print("Class getattribute invoked:", args) 
     return object.__getattribute__(self, name) 

c=C() 

अब इसी उत्पादन के साथ निम्नलिखित लाइनों की जांच:

>> C.__new__ 
Metaclass getattribute invoked: <class '__main__.C'> 
<built-in method __new__ of type object at 0x1E1B80B0> 

>> C.__getattribute__ 
Metaclass getattribute invoked: <class '__main__.C'> 
<function __getattribute__ at 0x01457F18> 

>> C.xyz 
Metaclass getattribute invoked: <class '__main__.C'> 
Metaclass getattr invoked: xyz 
None 

>> c.__new__ 
Class getattribute invoked: (<__main__.C object at 0x013E7550>, '__new__') 
<built-in method __new__ of type object at 0x1E1B80B0> 

>> c.__getattribute__ 
Class getattribute invoked: (<__main__.C object at 0x01438DB0>, '__getattribute__') 
Metaclass getattribute invoked: <class '__main__.C'> 
<bound method C.__getattribute__ of <__main__.C object at 0x01438DB0>> 

>> 

निष्कर्ष मैं किया गया है (पर विचार हम x.foo लिए खोज कर रहे) कर रहे हैं:

निम्नलिखित अजगर कोड पर विचार करें
  • __getattribute__ < प्रकार 'प्रकार'> और < प्रकार 'ऑब्जेक्ट'> के उदाहरणों के लिए अलग है। सीएफयू() के लिए, 'foo' पहली बार सी .__ dict__ पर खोजा जाता है और यदि पाया जाता है (खोज प्रकार (सी) के बजाय) और x.foo() 'foo' के लिए टाइप (x) .__ dict__ पर खोजा जाता है और x .__ dict__ पर।
  • __getattribute__ विधि हमेशा प्रकार (x) पर हल हो जाती है, जो मुझे समझ में नहीं आता है आखिरी मामला है: c .__ getattribute__, ऑब्जेक्ट में कोई विधि नहीं है __getattribute__ (और वस्तु से विरासत प्राप्त होती है), तो मेटाक्लास क्यों Getattribute विधि बुलाया जाता है।

क्या कोई इसे समझा सकता है ?? या कम से कम मुझे बताओ कि मुझे इसके बारे में कुछ दस्तावेज कहां मिल सकता है, धन्यवाद।

उत्तर

4

यदि आप print("Metaclass getattribute invoked:", self, name) जोड़ा आप देखना चाहते हैं:

>>> c.__getattribute__ 
Class getattribute invoked: <__main__.C object at 0x2acdbb1430d0> __getattribute__ 
Metaclass getattribute invoked: <class '__main__.C'> __name__ 
<bound method C.__getattribute__ of <__main__.C object at 0x2acdbb1430d0>> 

metaclass __getattribute__ आदेश, अभिव्यक्ति c.__getattribute__ की repr का निर्माण करने में लागू किया जा रहा है ताकि यह मुद्रित कर सकते हैं C के __name__

बीटीडब्ल्यू, __getattribute__ कक्षाओं और मेटाक्लास के लिए समान कार्य करता है; उदाहरण के उदाहरण पर उदाहरण को पहले उदाहरण पर देखा जाता है।

>>> Meta.foo = 1 
>>> C.foo 
('Metaclass getattribute invoked:', <class '__main__.C'>, 'foo') 
1 
>>> c.foo 
('Class getattribute invoked:', <__main__.C object at 0x2acdbb1430d0>, 'foo') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 5, in __getattribute__ 
AttributeError: 'C' object has no attribute 'foo' 
>>> C.bar = 2 
>>> c.bar 
('Class getattribute invoked:', <__main__.C object at 0x2acdbb1430d0>, 'bar') 
2 
+2

पायथन प्रकार और ऑब्जेक्ट्स http://www.cafepy.com/article/python_types_and_objects/ – amirouche

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

  • कोई संबंधित समस्या नहीं^_^