functools.singledispatch等效于super()

时间:2014-08-29 04:06:53

标签: python python-3.x super method-resolution-order functools

functools.singledispatch有助于定义单调度泛型方法。同时,调用方法或访问超类的属性有super()

是否有super()可以与singledispatch一起使用?我尝试了以下操作,但super(Derived, value)的结果不是Base的实例,因此它无法正常工作:

from functools import singledispatch

@singledispatch
def hello(value):
    return ['default']

@hello.register(Base)
def hello_base(value):
    return hello(super(Base, value)) + ['base']

@hello.register(Derived)
def hello_derived(value):
    return hello(super(Derived, value)) + ['derived']

print(hello(Derived())
# expected ['default', 'base', 'derived'],
# but actually is ['default', 'derived'].

1 个答案:

答案 0 :(得分:2)

我相信这样的东西会起作用,但由于我没有安装Python 3.4,所以我无法测试它:

def getsuperclass(cls):
    try:
        nextclass = cls.__mro__[1]
    except IndexError:
        raise TypeError("No superclass")
    return nextclass

@singledispatch
def hello(value):
    return ['default']

@hello.register(Base)
def hello_base(value):
    return hello.dispatch(getsuperclass(Base))(value) + ['base']

@hello.register(Derived)
def hello_derived(value):
    return hello.dispatch(getsuperclass(Derived))(value) + ['derived']

print(hello(Derived()))

请注意,使用超类作为参数调用hello并不合理,因为如果这样做,您将丢失传递的原始参数(value)。在你的情况下,它并不重要,因为你的函数根本不使用value,但真正的调度函数实际上可能会对值做一些事情,所以你需要将值作为参数传递。