Python:绑定方法

0 投票
3 回答
2667 浏览
提问于 2025-04-15 16:11

在下面的例子中,我试图通过 types.MethodType(...) 来绑定一个方法对象。但看起来并没有成功。有什么建议吗?提前谢谢你们。

import types

class Base:
    def payload(self, *args): 
        print "Base:payload"

class Drvd(Base):
    def iter(self, func):
        derived_func = types.MethodType(func, self, Drvd) # bind
        print "drvd_func:", derived_func 
        derived_func() # result:  calls Base:payload 
                       # expected:calls Drvd:payload; why???
    def payload(self, *args):
        print "Drvd:payload"

derived   = Drvd()           
base_func = Base.payload      
print "base_func:", base_func
derived.iter(base_func)  # pass unbound method object

输出结果显示:

base_func: <未绑定的方法 Base.payload>
drvd_func: <绑定的方法 Drvd.payload,属于 <main.Drvd 实例,地址在 0x00B51648>>
Base:payload

3 个回答

0

我不太明白你想要做什么,但对我来说,它的工作方式是我所期待的。你把 Base.payload 绑定到了 Drvd 上,从你的输出中可以看到,它确实正确地绑定到了你的 Drvd 实例上。我不明白你为什么还期待它去调用 Drvd.payload,因为你绑定的是函数对象 Base.payload。它始终都是那个函数。

[补充说明:如果你能简单说一下你想做的事情,那可能会更有帮助。你现在做的事情不太合理——Python 有继承功能,如果你想重写 payload 方法,你可以直接这样做,不需要手动绑定。]

1

因为你把Base的负载(而不是Drvd的)传给了iter!

提示:

print "%s: Base:payload"%repr(self)

不过,给你点赞,创造了一个奇怪的混合体!

2

你特别要求使用Base.payload的底层功能(im_func),并且用一个假的im_class,也就是Drvd。在iter中的现有print后面加上:

    print "w/class:", derived_func.im_class
    print "w/func:", derived_func.im_func

这样你就能看到总的输出是:

$ python bou.py 
base_func: <unbound method Base.payload>
drvd_func: <bound method Drvd.payload of <__main__.Drvd instance at 0x24a918>>
w/class: __main__.Drvd
w/func: <unbound method Base.payload>
Base:payload

也就是说,正如你所要求的,实际上使用的底层代码确实是Base.payload——这也是你在调用中观察到的。

Base.payload直接到Drvd.payload没有简单的方法,唯一的办法是先获取名称,然后用这个名称在self(一个Drvd实例)上使用getattr,或者用类似的方法。

撰写回答