2012-04-29 34 views
10

我想動態地分配函數實現。在Python中動態分配函數實現

讓我們先從以下:

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一個匿名函數,並將其分配給對象。但不支持Python中的匿名函數。相反,我們會盡力做一個可調用的類的實例,並分配到類:

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

所以我正在尋找pythonic的方式來分配一個匿名函數的類函數或實例方法,其中方法調用可以引用對象的self

+0

您拒絕的第一種方法沒有任何問題。你爲什麼這麼複雜? –

+2

您的錯誤真的很奇怪 - 您是否嘗試使用Ruby解釋器運行Python腳本? (你的文件叫做'prog.rb','.py'是Python文件的擴展名)。這個錯誤肯定不是來自Python--'self'不是Python中的關鍵字。 –

+0

我的錯誤 - 用ruby設置在線鍵盤上運行它 - 修復了 – 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 

匿名函數有什麼用此做(順便說一下,Python支持由單一的表現形式簡單匿名函數,見lambda)。

+0

+1匿名在這裏並不重要 - 重要的是你可以指定一個功能。 –

+0

感謝這很好 - 不知道爲什麼我認爲它不是 – Yarin

19

犛牛的答案很好,如果你想改變一個類的每個實例的東西。

如果你想改變方法只爲對象的特定實例,而不是整個類,你需要使用MethodType類型構造函數來創建一個綁定方法:

from types import MethodType 

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

@ Amber-謝謝你 – Yarin

+1

至少在Python 3中,它應該是'doer.doSomething = MethodType(doItBetter,doer)'。 方法和函數的不同情況的一個很好的解釋在http://stackoverflow.com/questions/972/adding-a-method-to-an-existing-object-instance – yanlend

+0

@yanlend這個問題被要求爲Python 2。 – Amber