I have a fancyfunction
defined to do something to a single argument. I decorate it to become a generic function so that it knows what to do if it is given a tuple.
from functools import singledispatch
@singledispatch
def fancyfunction(arg):
print(arg)
@fancyfunction.register
def _(arg: tuple):
for a in arg:
fancyfunction(a)
Sure enough the valid call signatures for the two functions above are:
fancyfunction(foo)
fancyfunction((foo, bar, ...))
I want to simplify the call signatures so that I don't need the extra pair of parentheses:
fancyfunction(foo)
fancyfunction(foo, bar, baz, ...)
In order to do that, I need the overloaded function to unpack its positional arguments:
@singledispatch
def fancyfunction(arg):
print(arg)
@fancyfunction.register
def _(*arg):
for a in arg:
fancyfunction(a)
Of course the last code snippet above doesn't work. Doing this:
fancyfunction(foo, bar, baz)
would call the generic function instead of the overloaded function.
Is it possible to make singledispatch
recognize that the decorated function is called with *
-form of arguments? P.S. What is the official name of that kind of call signature?
It's a bit confusing - you say you want to "tell" the function what to do when first argument is tuple, yet you don't want to pass tuple (i.e. you don't want the brackets). it looks it's a third case - you want to pass tuple, but also to be able to pass multiple arguments.
maybe something along these lines
from functools import singledispatch
@singledispatch
def fancyfunction(arg, *args):
print(arg)
for a in args:
print(a)
@fancyfunction.register
def _(arg: tuple, *args):
fancyfunction(*(*arg, *args))
another option is to have a helperfunction
from functools import singledispatch
def fancyfunction(*args):
for a in args:
helperfunction(a)
@singledispatch
def helperfunction(arg):
print(arg)
@helperfunction.register
def _(arg: tuple):
for a in arg:
helperfunction(a)
in both cases calling like this
fancyfunction(1)
fancyfunction(2, 3)
fancyfunction((4,5))
fancyfunction((6, 7) ,8, 9)
fancyfunction((10, 11), (12, 13))
fancyfunction([14, 15])
will yield following output
1
2
3
4
5
6
7
8
9
10
11
(12, 13)
[14, 15]
>>>