【问题标题】:Python: Binding methodPython:绑定方法
【发布时间】:2009-11-19 19:30:29
【问题描述】:

在以下示例中,我尝试通过 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:
drvd_func: ma​​in.Drvd 实例的绑定方法 Drvd.payload 在 0x00B51648>>
基数:有效载荷

【问题讨论】:

  • 既然子类继承了超类的功能,那你为什么要这样做呢?有什么意义?
  • Alex 已经指出,原来的未绑定方法 Base.payload 不能转换为另一个同名的类成员函数。即使是继承的类。我目前正在设置树迭代。看起来我应该使用访问者/多方法方法,或者每个有效负载处理程序都有 ID,每个节点都有一个调度程序。它将用于存储来自 Sax 解析器的 XML 输出-
  • 尽可能使用访客。避免魔法。

标签: python binding types methods bind


【解决方案1】:

您特别要求使用 Base.payload 的底层函数 (im_func),以及 Drvd 的假 im_class。在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,除非通过获取名称并使用它在selfDrvd 实例)上执行getattr,或等效。

【讨论】:

  • 感谢您的澄清。传递的未绑定函数的名称确实是 Base 和 Drvd 实现之间的唯一链接。
【解决方案2】:

因为您将 Base 的有效载荷(而不是 Drvd 的)传递给了 iter!

提示:

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

感谢你创造了一个该死的嵌合体!

【讨论】:

    【解决方案3】:

    我真的不明白你想要做什么 - 但对我来说它正在按我的预期工作。您正在将 Base.payload 绑定到 Drvd - 从您的打印输出中您可以看到它已正确绑定到您的 Drvd 实例。我不确定你为什么期望它调用 Drvd.payload - 你已经绑定了函数对象 Base.payload。它永远是那个功能。

    [编辑:只是补充一下-如果您笼统地说出您要做什么,这可能会有所帮助。你现在做的事情没有多大意义——Python有继承,所以如果你想覆盖payload方法,你可以这样做——你不需要做任何手动绑定。]

    【讨论】:

    • 与访问者模式或多方法方法相比,我正在尝试减少对树状节点结构进行 tarversing 的编码工作。尽管弯曲 python 的底层方法签名,但它似乎成为一种 hack。
    猜你喜欢
    • 2010-11-04
    • 2017-11-06
    • 2017-07-19
    • 1970-01-01
    • 2011-04-03
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多