6

functools.singledispatch помогает определить общий метод отправки. Между тем, существует super() для вызова методов или доступа к атрибутам суперкласса.Эквивалент супер() для functools.singledispatch

Есть ли что-то вроде 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']. 

ответ

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, но реальная диспетчерская функция, вероятно, действительно сделает что-то со значением, поэтому вам нужно передать значение в качестве аргумента.