Python中的泛型函数 - 以未知参数数量调用方法
我刚学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
太好了!