19

我想动态分配一个函数实现。

让我们从以下内容开始:

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()

这给了我这个:

回溯(最后一次调用):第 13 行,在 doer.doSomething() 中第 9 行,调用 打印“%s 做得更好” % 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 ,它就可以工作,但是当我这样做时,它会给我一个名称错误,self.name因为它引用的是可调用的self,而不是拥有的类self

所以我正在寻找一种pythonic方法来将匿名函数分配给类函数或实例方法,其中方法调用可以引用对象的self.

4

2 回答 2

34

你的第一种方法是好的,你只需要将函数分配给类:

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)。

于 2012-04-29T18:03:24.873 回答
34

如果您想为类的每个实例更改某些内容,yak 的答案非常有用。

如果您只想为对象的特定实例而不是整个类更改方法,则需要使用MethodType类型构造函数来创建绑定方法:

from types import MethodType

doer.doSomething = MethodType(doItBetter, doer)
于 2012-04-29T18:11:51.530 回答