-1

我已经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识别装饰函数是使用*-form of arguments 调用的?PS这种呼叫签名的正式名称是什么?

4

1 回答 1

2

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

也许沿着这些思路

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]
>>>
于 2019-06-05T08:27:26.417 回答