python中的泛型函数-调用具有未知参数数的方法

python中的泛型函数-调用具有未知参数数的方法,python,generics,Python,Generics,我是python新手,需要一些帮助 我正在实现一个通用的搜索函数,它接受一个参数“条纹”,它可以是多种类型的数据结构 在搜索方法中,我有一行: fringe.push(item, priority) 问题在于,不同数据结构中的push方法采用不同数量的参数(有些需要优先级,有些不需要)。有没有一种更高级的方法来获得pass,并使“push”方法只从发送的参数列表中获取所需的参数数 谢谢 不能只使用默认参数值吗 >>> def foo(a, b = 10): ... pr

我是python新手,需要一些帮助

我正在实现一个通用的搜索函数,它接受一个参数“条纹”,它可以是多种类型的数据结构

在搜索方法中,我有一行:

 fringe.push(item, priority)
问题在于,不同数据结构中的push方法采用不同数量的参数(有些需要优先级,有些不需要)。有没有一种更高级的方法来获得pass,并使“push”方法只从发送的参数列表中获取所需的参数数


谢谢

不能只使用默认参数值吗

>>> def foo(a, b = 10):
...   print a, b
... 
>>> foo(1000)
1000 10
>>> foo(1000, 1000)
1000 1000
>>>

如果未提供参数
b
,则默认为
10

请尝试下面的代码片段

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


args = (1,)
push(*args)

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

获取不同数量的参数并仍然能够选择正确参数的方法是使用*args和**关键字_args参数。 来自Mark Lutz的
学习Python
一书:

*
***
旨在支持采用任意数量参数的函数。两者都可以出现在函数定义或 函数调用,它们在这两个位置有相关的用途

函数定义中的
**
**
如果您定义了一个函数:

def f1(param1, *argparams, **kwparams): 
    print 'fixed_params -> ', param1
    print 'argparams  --> ', argparams
    print 'kwparams   ---->,', kwparams
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 
你可以这样称呼它:

f1('a', 'b', 'c', 'd', kw1='keyw1', kw2='keyw2')
然后你会得到:

fixed_params ->  a
argparams  -->  ('b', 'c', 'd')
kwparams   ---->, {'kw1': 'keyw1', 'kw2': 'keyw2'}
因此,您可以发送/接收任意数量的参数和关键字。 恢复关键字args的一个典型习惯用法如下:

def f1(param1, **kwparams):
    my_kw1 = kwparams['kw1']
    ---- operate  with my_kw1 ------
通过这种方式,可以使用任意数量的参数调用函数,并使用所需的参数。
这种类型或参数经常在一些GUI代码中使用,如wxPython类定义和子类化,以及函数curry、decorator等

函数调用中的
**
**
函数调用中的
*
**
参数在函数执行时会被解包:

def f1(param1, *argparams, **kwparams): 
    print 'fixed_params -> ', param1
    print 'argparams  --> ', argparams
    print 'kwparams   ---->,', kwparams
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 

太好了

理论上,您可以使用
inspect.getargspec(borge)
来找出该方法采用的参数。这将告诉您可以传递的参数数量,但它非常混乱:

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…除了

如果我理解正确-这需要更改每个数据结构中的push方法,条纹可以。。。因为我希望搜索函数是通用的,所以我希望它能够与现有的数据结构一起工作。操作需要在搜索方法本身中进行。有没有一个好的方法可以做到这一点?您必须查看哪些数据类型需要参数,哪些不需要参数。您可以(不推荐)使用
try,但
块和尝试在不带参数的情况下运行
.push
。如果它断开,请尝试该参数。不过,我怀疑它是否会很快。这如何解决我认为调用一个可能接受一个或两个参数但调用方不知道是哪个参数的现有函数的问题?@Duncan如果你不知道要发送哪些参数,那么你要么反思该方法,您可以在出现异常时播放try/failure,或者发送所有可能的已知参数,并让不同的对象方法获得所需的参数。最后一种方法是严格的,在许多情况下相当普遍。对于OP示例,只需使用关键字默认参数即可解决问题。由于我不确定OP谈论的是一个或两个论点,还是更一般的一个或多个论点,我给了他一个一般性的观点或*args和**kargs。希望他觉得有用这是一个很好的答案,如果你能改变你正在调用的函数的定义。如果不是,像邓肯这样的回答似乎是必要的。库开发人员可以通过让用户定义的回调方法采用*args和**kwargs来避免这个问题。这将允许您在将来无限期地向回调添加参数,而无需中断任何内容或检查回调。这种方法对我来说是必要的情况是,在处理库时,我希望保持旧回调签名向后兼容。在本例中,我有点担心会出现TypeError,因为我不知道它是来自回调签名还是来自用户回调代码中的某个异常。