Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Equivalent to super() for functools.singledispatch

functools.singledispatch helps to define a single-dispatch generic method. Meanwhile, there is super() for calling methods or accessing attributes of a superclass.

Is there something like super() that can be used with singledispatch? I tried the following, but the result of super(Derived, value) is just not instance of Base, so it does not work as I expected:

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'].
like image 836
minhee Avatar asked Aug 29 '14 04:08

minhee


People also ask

What is Singledispatch in Python?

The singledispatch decorator is used for function overloading. The decorator turns a function into a generic function that can have different implementations depending on the function's first argument.

How do you use Singledispatch?

To use singledispatch , simply: add the decorator @singledispatch to the function process_data. add the decorator @process_data. register to process_dict and process_list .


1 Answers

I believe that something like this will work, but I can't test it since I don't have Python 3.4 installed:

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

Note that it doesn't really make sense to call hello with the superclass as the argument, because if you did that you would lose the original argument (value) that was passed. In your case it doesn't matter because your function doesn't use value at all, but a real dispatch function would probably actually do something with the value, so you need to pass the value as the argument.

like image 164
BrenBarn Avatar answered Oct 29 '22 21:10

BrenBarn