2016-02-10 6 views
6

मैंने देखा कि यदि मैं उस वर्ग का उदाहरण बनाते समय एक फ़ंक्शन के बराबर कक्षा विशेषता परिभाषित करता हूं तो विशेषता एक बाध्य विधि बन जाती है। क्या कोई मुझे इस व्यवहार का कारण बता सकता है?पायथन - क्लास एट्रिब्यूट के रूप में फ़ंक्शन एक बाध्य विधि बन जाता है

In [9]: def func(): 
    ...:  pass 
    ...: 

In [10]: class A(object): 
    ....:  f = func 
    ....:  

In [11]: a = A() 

In [12]: a.f 
Out[12]: <bound method A.func of <__main__.A object at 0x104add190>> 

In [13]: a.f() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-13-19134f1ad9a8> in <module>() 
----> 1 a.f() 
    global a.f = <bound method A.func of <__main__.A object at 0x104add190>> 

TypeError: func() takes no arguments (1 given) 

उत्तर

7

आपने विशेषता f पर फ़ंक्शन को असाइन किया है। क्योंकि फ़ंक्शन अब कक्षा के अंदर है, यह एक विधि बन जाता है, विशेष रूप से एक बाध्य विधि (क्योंकि यह ऑब्जेक्ट से बाध्य है, further explanation here)।कक्षाओं में

तरीके, कम से कम एक पैरामीटर (self) प्राप्त जब तक यह विशेष रूप से नहीं करने के लिए कहा है - देखना class methods and static methods -, इस कारण के लिए त्रुटि का कहना है कि func (के रूप में यह def func(): रूप में परिभाषित किया गया है) लेकिन 1 प्राप्त नहीं तर्क लेता है (self)

ऐसा करने के लिए आप क्या चाहते हैं, तो आप है कि आप एक static method

def func(): 
    pass 

class A(object): 
    f = staticmethod(func) 
उपयोग कर रहे हैं अजगर को बताना चाहिए
1

अजगर नहीं संदेश आधारित OO प्रणाली है। इसके बजाए, जावास्क्रिप्ट के समान, गुण प्रथम श्रेणी के कार्यों के लिए हल किए जाते हैं और फिर बुलाए जाते हैं; खोज के रूप में, इस तरह के यांत्रिकी में व्यवहार थोड़ा अलग है।

अजगर में आवश्यकता है कि तरीकों कम से कम एक पैरामीटर, सामान्य रूप से self कहा जाता है, जो अपने आप हो जाएगा जुड़े उदाहरण आपूर्ति जब यह एक विधि के रूप लागू किया जाता है।

इसके अलावा (और शायद प्रश्न के बिंदु पर), पाइथन def f.. या f = some_func() का उपयोग करते समय उदाहरण सदस्य बाइंडिंग स्थापित करते समय अंतर नहीं करता है; तर्कसंगत रूप से यह कक्षाओं के बाहर व्यवहार से मेल खाता है।

उदाहरण में, फ़ंक्शन को आवंटित करने के लिए 'इसे एक उदाहरण विधि की तरह माना जाने की उम्मीद है'। यह सटीक वही है - पैरामीटर रहित - दोनों मामलों में फ़ंक्शन कहा जाता है; केवल भविष्य का उपयोग प्रासंगिक है।

अब जावास्क्रिप्ट के विपरीत, पाइथन बाध्य तरीकों की अवधारणा के माध्यम से विधियों और ऑब्जेक्ट एसोसिएशन को संभालता है - विधियों को हमेशा 'बाध्य' के रूप में हल किया जाता है।

a.f का व्यवहार एक बाध्य विधि लौटने का कार्य - फ़ंक्शन जो पहले पैरामीटर को self के रूप में स्वचालित रूप से बाध्य ऑब्जेक्ट की आपूर्ति करेगा - फ़ंक्शन के स्रोत से स्वतंत्र रूप से किया जाता है। इस मामले में इसका मतलब है कि पैरामीटर रहित फ़ंक्शन का उपयोग तब नहीं किया जा सकता जब यह 'बाध्य' होता है क्योंकि यह self पैरामीटर स्वीकार नहीं करता है।

एक प्रदर्शन के रूप में, निम्नलिखित उसी तरह से असफल हो जायेगी क्योंकि स्रोत अंतर्निहित विधि करता नहीं एक तर्क के रूप उदाहरण को स्वीकार करने की न्यूनतम आवश्यकताओं को पूरा:

g = a.f 
g() 

इस मामले बुला g() है func(a) पर कॉल करने के बराबर।


तुलना के लिए, जावा, सी #, रूबी, और SmallTalk संदेश आधारित OO प्रणालियों रहे हैं - इन में एक वस्तु, एक 'नाम' से एक विधि को लागू करने की बजाय एक विधि को हल करने के बारे में बताया जाता है (या फ़ंक्शन) एक मान के रूप में जिसे बुलाया जा सकता है।

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