2012-04-29 26 views
10

में गतिशील रूप से फ़ंक्शन कार्यान्वयन असाइन करना मैं गतिशील रूप से फ़ंक्शन कार्यान्वयन असाइन करना चाहता हूं।पाइथन

के निम्नलिखित साथ शुरू करते हैं:

class Doer(object): 

    def __init__(self): 
     self.name = "Bob" 

    def doSomething(self): 
     print "%s got it done" % self.name 

def doItBetter(self): 
    print "Done better" 

अन्य भाषाओं में हम एक गुमनाम समारोह doItBetter बनाने के लिए और वस्तु के लिए असाइन करें करेंगे। लेकिन पायथन में अज्ञात कार्यों के लिए कोई समर्थन नहीं है। इसके बजाय, हम एक प्रतिदेय वर्ग उदाहरण बनाने की कोशिश करेंगे, और वर्ग के लिए है कि आवंटित:

class Doer(object): 

    def __init__(self): 
     self.name = "Bob" 

class DoItBetter(object): 

    def __call__(self): 
     print "%s got it done better" % self.name 

Doer.doSomething = DoItBetter() 
doer = Doer() 
doer.doSomething() 

कि मुझे इस देता है:

Traceback (most recent call last): Line 13, in doer.doSomething() Line 9, in call print "%s got it done better" % self.name AttributeError: 'DoItBetter' object has no attribute 'name'

अंत में, मैं के रूप में वस्तु उदाहरण के लिए प्रतिदेय बताए की कोशिश की एक विशेषता है और यह बुला:

class Doer(object): 

    def __init__(self): 
     self.name = "Bob" 

class DoItBetter(object): 

    def __call__(self): 
     print "%s got it done better" % self.name 


doer = Doer() 
doer.doSomething = DoItBetter() 
doer.doSomething() 

यह रूप में लंबे समय से काम करता है मैं DoItBetter में स्वयं को संदर्भित नहीं है, लेकिन यह मुझे क्योंकि यह संदर्भित है self.name पर एक नाम त्रुटि देता है जब मैं करता हूँ कॉल करने योग्य self, मालिक वर्ग self नहीं है।

तो मैं क्लास फ़ंक्शन या इंस्टेंस विधि में अज्ञात फ़ंक्शन असाइन करने के लिए एक पाइथोनिक तरीका ढूंढ रहा हूं, जहां विधि कॉल ऑब्जेक्ट के self का संदर्भ दे सकती है।

+0

आपके द्वारा अस्वीकार किए गए पहले दृष्टिकोण के साथ कुछ भी गलत नहीं है। आप इसे इतना जटिल क्यों बना रहे हैं? –

+2

आपकी त्रुटि वास्तव में अजीब है - क्या आप एक रूबी दुभाषिया के साथ एक पायथन स्क्रिप्ट चलाने की कोशिश कर रहे हैं? (आपकी फ़ाइल को 'prog.rb' कहा जाता है,' .py' पायथन फ़ाइल एक्सटेंशन है)। त्रुटि निश्चित रूप से पायथन से नहीं है - 'self' पायथन में कोई कीवर्ड नहीं है। –

+0

मेरी गलती- इसे रूबी सेटिंग्स के साथ ऑनलाइन कोडपैड पर चलाया गया- निश्चित – Yarin

उत्तर

23

आपका पहला दृष्टिकोण ठीक था, तो आप सिर्फ वर्ग के लिए समारोह आवंटित करने के लिए है:

class Doer(object): 
    def __init__(self): 
     self.name = "Bob" 

    def doSomething(self): 
     print "%s got it done" % self.name 

def doItBetter(self): 
    print "%s got it done better" % self.name 

Doer.doSomething = doItBetter 

बेनामी कार्य (वैसे यह कोई लेना देना नहीं है, अजगर सरल गुमनाम एकल भाव से मिलकर कार्यों का समर्थन करता है , lambda देखें)।

+0

+1 अज्ञात होने पर कोई फर्क नहीं पड़ता - यह सब मायने रखता है कि आप एक असाइन कर सकते हैं समारोह। –

+0

धन्यवाद यह बहुत अच्छा काम करता है- सुनिश्चित नहीं है कि मैंने क्यों सोचा था कि यह – Yarin

19

याक का उत्तर बहुत अच्छा काम करता है यदि आप कक्षा के हर उदाहरण के लिए कुछ बदलना चाहते हैं।

आप और नहीं पूरी कक्षा के लिए केवल वस्तु की एक विशेष उदाहरण के लिए प्रक्रिया में परिवर्तन करना चाहते हैं, तो आप MethodType प्रकार निर्माता का उपयोग करने के लिए बाध्य विधि बनाने की आवश्यकता होगी:

from types import MethodType 

doer.doSomething = MethodType(doItBetter, doer, Doer) 
+0

@ एम्बर- इस – Yarin

+1

के लिए धन्यवाद, कम से कम पायथन 3 में, यह 'doer.doSomething = MethodType (doItBetter, doer)' होना चाहिए। विधियों और कार्यों के लिए विभिन्न मामलों का एक अच्छा स्पष्टीकरण http://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object-instance – yanlend

+0

@yanlend में इस प्रश्न के लिए पूछा गया था पायथन 2। – Amber