2009-11-04 8 views
7

मुझे यह समझने में परेशानी हो रही है कि एक वर्ग विधि ऑब्जेक्ट पाइथन में कैसे काम करता है, खासकर मेटाक्लास के संदर्भ में और __new__ में। मेरे विशेष मामले में मैं को दिए गए members के माध्यम से पुन: प्रयास करते समय क्लासमेड सदस्य का नाम प्राप्त करना चाहता हूं।क्लासमेड ऑब्जेक्ट कैसे काम करता है?

सामान्य तरीके के लिए नाम बस एक __name__ विशेषता में संग्रहीत किया जाता है, लेकिन एक classmethod के लिए जाहिरा तौर ऐसी कोई विशेषता है। मैं यह भी नहीं देखता कि क्लासमेड कैसे लगाया जाता है, क्योंकि __call__ विशेषता नहीं है।

क्या कोई मुझे बता सकता है कि क्लासमेड कैसे काम करता है या मुझे कुछ दस्तावेज में इंगित करता है? गुगलिंग ने मुझे कहीं भी नेतृत्व नहीं किया। धन्यवाद!

+0

मुझे "गायब" '__name__' के बारे में अंतर्दृष्टि नहीं है, लेकिन यह सुनिश्चित करने के लिए कि कक्षाओं के पास' __call__' wrapper है। – mjv

उत्तर

18

classmethod ऑब्जेक्ट एक वर्णनकर्ता है। आपको समझने की जरूरत है कि वर्णनकर्ता कैसे काम करते हैं। self, एक instance, और एक instance type:

संक्षेप में, एक विवरणक एक वस्तु है जो एक विधि __get__ है, जो तीन तर्क लेता है।

सामान्य विशेषता देखने के दौरान, यदि एक देखा-अप वस्तु A एक विधि __get__ है, उस विधि कहा जाता है और हो जाता है क्या यह रिटर्न वस्तु A के लिए जगह में दिया जाता है। जब आप ऑब्जेक्ट पर कोई विधि कॉल करते हैं तो इस तरह फ़ंक्शन (जो वर्णनकर्ता भी होते हैं) बाध्य विधियां बन जाते हैं।

class Foo(object): 
    def bar(self, arg1, arg2): 
     print arg1, arg2 

foo = Foo() 
# this: 
foo.bar(1,2) # prints '1 2' 
# does about the same thing as this: 
Foo.__dict__['bar'].__get__(foo, type(foo))(1,2) # prints '1 2' 

classmethod ऑब्जेक्ट एक ही तरीके से काम करता है। जब इसे देखा जाता है, तो इसकी __get__ विधि कॉल हो जाती है। __get__ क्लासमाइट के instance (अगर कोई था) से संबंधित तर्क को त्याग देता है और केवल instance_type के साथ गुजरता है जब यह लपेटा हुआ फ़ंक्शन पर __get__ पर कॉल करता है।

एक उदाहरण डूडल:

In [14]: def foo(cls): 
    ....:  print cls 
    ....:  
In [15]: classmethod(foo) 
Out[15]: <classmethod object at 0x756e50> 
In [16]: cm = classmethod(foo) 
In [17]: cm.__get__(None, dict) 
Out[17]: <bound method type.foo of <type 'dict'>> 
In [18]: cm.__get__(None, dict)() 
<type 'dict'> 
In [19]: cm.__get__({}, dict) 
Out[19]: <bound method type.foo of <type 'dict'>> 
In [20]: cm.__get__({}, dict)() 
<type 'dict'> 
In [21]: cm.__get__("Some bogus unused string", dict)() 
<type 'dict'> 

वर्णनकर्ता बारे में अधिक जानकारी यहां पाया जा सकता (अन्य स्थानों में): http://users.rcn.com/python/download/Descriptor.htm

समारोह एक classmethod से लिपटे के नाम होने का विशिष्ट कार्य के लिए :

In [29]: cm.__get__(None, dict).im_func.__name__ 
Out[29]: 'foo' 
+0

धन्यवाद, मेरी समस्या हल हो गई! मैं अब थोड़ा बेवकूफ महसूस करता हूं क्योंकि सिद्धांत रूप में मैं वर्णनकर्ताओं के बारे में जानता था। लेकिन मुझे यह देखने के लिए भ्रमित किया गया कि एक क्लासमेड एक गैर-कॉल करने योग्य वर्णनकर्ता में लपेटा गया है :-) – nikow

+0

क्षमा करें, मैं इस बात पर जोर देना भूल गया कि मैं आपके विस्तृत उत्तर की कितनी सराहना करता हूं, यह बहुत अच्छा है। – nikow

1

This ऐसा लगता है कि इसमें सामान है।

+0

धन्यवाद, मुझे मेटामाइड्स शब्द से अवगत नहीं था, इसलिए यह एक दिलचस्प पढ़ा गया था। लेकिन मुझे डर है कि क्लासमेड ऑब्जेक्ट पर ज्यादा जानकारी नहीं थी। – nikow

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