2014-08-29 25 views
6

functools.singledispatch hilft beim Definieren einer generischen Methode mit einem einzigen Versand. Inzwischen gibt es super() zum Aufruf von Methoden oder zum Zugriff auf Attribute einer Superklasse.Entspricht super() für functools.singledispatch

Gibt es etwas wie super(), das mit singledispatch verwendet werden kann? Ich habe versucht, die folgenden, aber das Ergebnis von super(Derived, value) ist einfach nicht Instanz Base, so dass es nicht funktioniert, wie ich es erwartet:

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']. 

Antwort

2

Ich glaube, dass so etwas wie dies funktionieren wird, aber ich kann es nicht testen, da ich habe nicht Python 3.4 installiert ist:

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

Beachten Sie, dass es nicht wirklich Sinn macht hello als Argument mit der übergeordneten Klasse zu nennen, denn wenn Sie getan haben, dass Sie das ursprüngliche Argument verlieren würden (value), dass war vergangen. In Ihrem Fall spielt es keine Rolle, denn Ihre Funktion verwendet value überhaupt nicht, aber eine echte Dispatch-Funktion würde wahrscheinlich etwas mit dem Wert tun, also müssen Sie den Wert als Argument übergeben.