通过字典调用函数时不传递参数

15

我写了一个Python脚本,根据用户的输入调用函数。到目前为止,我只是简单地通过字典调用没有参数的函数。

options = { 0 : func0,
            1 : func1,
            2 : func2,
           }
options[choice]()

现在我处于需要调用一些带有参数的函数的情况。我是 Python 的新手,我尝试了如下代码:

options = { 0 : (func0,None),
            1 : (func1,None),
            2 : (func2,foo1),
            3 : (func3,foo2),
          }
options[choice][0](options[choice][1])

我知道为什么在这里使用 None 不起作用,并且只是写它来表示该函数不接受任何参数。我应该如何修改代码,使其适用于所有类型的函数?

我尝试了解包装空字典,但它也不起作用。

4个回答

26

None 仍然是一个值,将其传递给不期望参数的函数将不起作用。相反,考虑在这里使用partial

from functools import partial

options = { 0: func0,
            1: func1,
            2: partial(func2, foo1),
            3: partial(func3, foo2),
          }

options[choice]()

18
使用参数列表:
options = { 0 : (func0, []),
            1 : (func1, []),
            2 : (func2, [foo1]),
            3 : (func3, [foo2]),
          }
options[choice][0](*options[choice][1])
# or
func, args = options[choice]
func(*args)

如果您想要能够指定命名参数,您可以按照以下方式进行扩展:

options = { 0 : (func0, [], {}),
            1 : (func1, [], {param_name: value}),
            2 : (print_name, [], {name: "nims"}),
            3 : (func3, [foo2], {}),
          }
func, args, kwargs = options[choice]
func(*args, **kwargs)

1
OP 可以考虑在 *args 后面再加上 **kwargs,作为一个字典来存储。 - jamylak
@jamylak:好主意,我会将其添加到我的帖子中。 - phant0m
2
@jamylak:哦,谢谢你的编辑,现在那是一个解包失败 :) - phant0m
3
请注意,在gnibbler的解决方案中,您可以非常自然地这样做:partial(func, foo1, p_name=foo2) - phant0m

4
你可以使用Lambda表达式为带有参数的函数提供实现(对于那些没有参数的函数,您可以像目前一样保持不变):
options = { 0 : func0,
            1 : func1,
            2 : lambda: func2(foo1),
            3 : lambda: func3(foo2),
          }

我非常喜欢“partial”解决方案,这是做这种方法的最佳途径。 - jamylak
2
同意,它还可以优雅地传递额外的参数。 - phant0m
在这种情况下有什么巨大的优势? - Michael Mauderer
在gnibbler的解决方案中,您可以向options[choice]()添加参数,这些参数将传递给原始函数。您必须像这样扩展您的lambdalambda *args,**kwargs:func2(foo1,*args,**kwargs),我认为这不是非常优雅的。 - phant0m
@jamylak 要使这个工作起来:options[choice](shared_name=shared_param),是的,他必须做所有这些。但在实践中是否需要这样做是一个不同的问题。在gnibbler的代码中,不需要进行任何修改就可以允许这样做。 - phant0m
显示剩余2条评论

1
尝试像这样做:
在函数头中使用*,它将收集所有参数到一个元组中。
def func0(*a):
    print list(a)
def func1(*a):
    print list(a)
def func2(*a):
    print list(a)
def func3(*a):
    print list(a)
foo1=1
foo2=2
options = { 0 : (func0,None),
            1 : (func1,None),
            2 : (func2,foo1),
            3 : (func3,foo2),
          }
choice=2
options[choice][0](options[choice][1:])  #prints [(1,)]

choice=1
options[choice][0](options[choice][1:])  #prints [(None,)]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接