2011-09-20 11 views
5

मुझे पता है तुम एक वर्ग के उदाहरण के लिए एक विधि को जोड़ने के लिए आप इस तरह एक साधारण काम नहीं कर सकता चाहते हैं:पायथन 3: क्लास इंस्टेंस के साथ बाध्य विधि .__ प्राप्त करें __(), यह काम करता है लेकिन क्यों?

>>> def print_var(self): # method to be added 
     print(self.var) 
>>> class MyClass: 
     var = 5 
>>> c = MyClass() 
>>> c.print_var = print_var 

यह वास्तव में print_var कारण एक सामान्य समारोह की तरह व्यवहार करने के लिए होगा, इसलिए self तर्क wouldn 'टी अपने ठेठ अर्थ है:

>>> import types 
>>> c.print_var = types.MethodType(print_var, c) 
>>> c.print_var 
<bound method MyClass.print_var of <__main__.MyClass object at 0x98a1bac>> 
>>> c.print_var() 
5 
:

>>> c.print_var 
<function print_var at 0x98e86ec> 
>>> c.print_var() 
Traceback (most recent call last): 
    File "<pyshell#149>", line 1, in <module> 
    c.print_var() 
TypeError: print_var() takes exactly 1 argument (0 given) 

आदेश समारोह कराने के लिए एक विधि पर विचार किया जाना (यानी यह उदाहरण के लिए बाध्य करने के लिए), मैं इस कोड का उपयोग करने के लिए इस्तेमाल

लेकिन मैंने पाया कि .__get__ भी इस उद्देश्य के लिए इस्तेमाल किया जा सकता है:

>>> c.print_var = print_var.__get__(c) 
>>> c.print_var 
<bound method MyClass.print_var of <__main__.MyClass object at 0x98a1bac>> 
>>> c.print_var() 
5 

समस्या यहाँ कि यह सिर्फ काम करता है, लेकिन मैं नहीं समझ सकता कि कैसे और क्यों। .__get__ के बारे में प्रलेखन बहुत मदद नहीं करता है।

अगर कोई पाइथन के दुभाषिया के इस व्यवहार को स्पष्ट कर सकता है तो मैं सराहना करता हूं।

उत्तर

5

जानकारी आप देख रहे हैं Descriptor HowTo Guide में है:

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

class Function(object): 
    . . . 
    def __get__(self, obj, objtype=None): 
     "Simulate func_descr_get() in Objects/funcobject.c" 
     return types.MethodType(self, obj, objtype) 

वास्तव में कुछ अजीब हो रहा नहीं है - एक समारोह वस्तु की __get__ विधि types.MethodType कॉल करता है और परिणाम देता है।

+1

पायथन 3 'विधि टाइप()' केवल 2 तर्क स्वीकार करता है। – joeforker

+0

@joeforker मैं पाइथन दस्तावेज़ों से उद्धरण दे रहा हूं, ऐसा लगता है कि उन्हें अपडेट करने की आवश्यकता है। – agf

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