解压后的多个参数上的单个调度

singledispatch on unpacked multiple arguments

我有一个 fancyfunction 定义为对单个参数执行某些操作。我把它装饰成一个通用函数,这样它就知道如果给它一个元组该怎么做。

from functools import singledispatch

@singledispatch
def fancyfunction(arg):
    print(arg)

@fancyfunction.register
def _(arg: tuple):
    for a in arg:
        fancyfunction(a)

果然,上面两个函数的有效调用签名是:

fancyfunction(foo)
fancyfunction((foo, bar, ...))

我想做什么

我想简化调用签名,这样我就不需要额外的一对括号了:

fancyfunction(foo)
fancyfunction(foo, bar, baz, ...)

为此,我需要重载函数来解压其位置参数:

@singledispatch
def fancyfunction(arg):
    print(arg)

@fancyfunction.register
def _(*arg):
    for a in arg:
        fancyfunction(a)

当然,上面的最后一个代码片段不起作用。这样做:

fancyfunction(foo, bar, baz)

将调用泛型函数而不是重载函数。

是否可以让 singledispatch 识别装饰函数是用 * 形式的参数调用的? P.S。那种调用签名的正式名称是什么?

这有点令人困惑 - 你说你想 "tell" 函数当第一个参数是元组时要做什么,但你不想传递元组(即你不想要括号) .它看起来是第三种情况 - 你想传递元组,但也能够传递多个参数。

也许是这样的

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

另一种选择是使用辅助函数

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)

在这两种情况下都这样调用

fancyfunction(1)
fancyfunction(2, 3)
fancyfunction((4,5))
fancyfunction((6, 7) ,8, 9)
fancyfunction((10, 11), (12, 13))
fancyfunction([14, 15])

将产生以下输出

1
2
3
4
5
6
7
8
9
10
11
(12, 13)
[14, 15]
>>>