Python中的泛型函数 - 以未知参数数量调用方法

8 投票
4 回答
11560 浏览
提问于 2025-04-17 06:25

我刚学Python,需要一些帮助...

我正在实现一个通用的搜索功能,这个功能接受一个叫“fringe”的参数,这个参数可以是多种类型的数据结构。

在搜索方法中,我有这样一行代码:

 fringe.push(item, priority)

问题是,不同的数据结构中的push方法需要的参数数量不同(有些需要优先级,有些则不需要)。有没有什么简单的方法可以解决这个问题,让“push”方法只接受它所需的参数,而不是接受所有传入的参数呢?

谢谢!

4 个回答

1

试试下面的代码片段,

def push(item, priority=None):
    print item,priority


args = (1,)
push(*args)

args = (1,2)
push(*args)
2

理论上,你可以用 inspect.getargspec(fringe) 来查看这个方法需要什么参数。这样你就能知道可以传多少个参数,但这个方法有点复杂:

argspec = inspect.getargspec(fringe.push)
if len(argspec.args) >= 3 or argspec.varargs or argspec.keywords:
    fringe.push(item, priority)
else:
    fringe.push(item)

其实更简单的做法是直接试一下,如果出错了再处理错误:

try:
    fringe.push(item, priority)
except TypeError:
    fringe.push(item)

当然,最好的办法是确保所有的 push() 方法都有一致的参数设置,但如果做不到这一点,那就用 try...except 来处理错误。

16

要让一个函数能够接受不同数量的参数,并且能够正确选择使用哪个参数,我们可以使用 *args**keyword_args 这两种参数。这个概念来自于 Mark Lutz 的书《学习Python》。

*** 是为了支持可以接受任意数量参数的函数而设计的。这两者可以出现在函数的定义中,也可以在调用函数时使用,它们在这两种情况下的作用是相关的。

*** 在函数定义中

如果你定义一个函数:

def f1(param1, *argparams, **kwparams): 
    print 'fixed_params -> ', param1
    print 'argparams  --> ', argparams
    print 'kwparams   ---->,', kwparams

你可以这样调用它:

f1('a', 'b', 'c', 'd', kw1='keyw1', kw2='keyw2')

然后你会得到:

fixed_params ->  a
argparams  -->  ('b', 'c', 'd')
kwparams   ---->, {'kw1': 'keyw1', 'kw2': 'keyw2'}

这样你就可以发送和接收任意数量的参数和关键字参数。一个常见的用法来获取关键字参数如下:

def f1(param1, **kwparams):
    my_kw1 = kwparams['kw1']
    ---- operate  with my_kw1 ------

这样你的函数就可以用任意数量的参数调用,并且只使用它需要的那些参数。
这种类型的参数经常在一些图形用户界面(GUI)代码中使用,比如 wxPython 的类定义和子类化,以及函数柯里化、装饰器等。

*** 在函数调用中

在函数调用中,*** 的参数在被函数接收时会被展开:

def func(a, b, c, d):
    print(a, b, c, d)

args = (2, 3)
kwargs = {'d': 4}
func(1, *args, **kwargs)

### returns ---> 1 2 3 4 

太好了!

撰写回答