你能列出一个Python函数接收的关键字参数吗?

我有一个字典,我需要传递键/值作为关键字参数..例如..

d_args = {'kw1': 'value1', 'kw2': 'value2'} example(**d_args) 

这个工作正常, 但是如果d_args字典中的值不被example函数所接受,那么显然会死亡。假设示例函数被定义为def example(kw2):

这是一个问题,因为我不控制d_args的生成或example函数。它们都来自外部模块,并且example只接受字典中的一些关键字参数。

理想情况下,我会做

 parsed_kwargs = feedparser.parse(the_url) valid_kwargs = get_valid_kwargs(parsed_kwargs, valid_for = PyRSS2Gen.RSS2) PyRSS2Gen.RSS2(**valid_kwargs) 

我可能只是从有效的关键字参数列表中筛选字典,但我想知道: 是否有一种方法编程方式列出特定function所需的关键字参数?

比直接检查代码对象更好一些,解决variables是使用检查模块。

 >>> import inspect >>> def func(a,b,c=42, *args, **kwargs): pass >>> inspect.getargspec(func) (['a', 'b', 'c'], 'args', 'kwargs', (42,)) 

如果你想知道它是否可以用一组特定的参数调用,那么你需要没有默认指定的参数。 这些可以通过:

 def getRequiredArgs(func): args, varargs, varkw, defaults = inspect.getargspec(func) if defaults: args = args[:-len(defaults)] return args # *args and **kwargs are not required, so ignore them. 

然后一个函数来告诉你从你的特定字典中缺less的是:

 def missingArgs(func, argdict): return set(getRequiredArgs(func)).difference(argdict) 

同样,要检查无效的参数,请使用:

 def invalidArgs(func, argdict): args, varargs, varkw, defaults = inspect.getargspec(func) if varkw: return set() # All accepted return set(argdict) - set(args) 

如果可以被调用,那么一个完整的testing是:

 def isCallableWithArgs(func, argdict): return not missingArgs(func, argdict) and not invalidArgs(func, argdict) 

(这只是python的argparsing的好处,任何运行时检查kwargs中的无效值显然都不能被检测到。)

这将打印所有可通过参数的关键字和非关键字的名字:

 def func(one, two="value"): y = one, two return y print func.func_code.co_varnames[:func.func_code.co_argcount] 

这是因为第一个co_varnames总是参数(接下来是局部variables,如上例中的y )。

所以现在你可以有一个function:

 def getValidArgs(func, argsDict): '''Return dictionary without invalid function arguments.''' validArgs = func.func_code.co_varnames[:func.func_code.co_argcount] return dict((key, value) for key, value in argsDict.iteritems() if key in validArgs) 

你可以这样使用:

 >>> func(**getValidArgs(func, args)) 

编辑 :一个小的补充:如果你真的只需要一个函数的关键字参数 ,你可以使用func_defaults属性来提取它们:

 def getValidKwargs(func, argsDict): validArgs = func.func_code.co_varnames[:func.func_code.co_argcount] kwargsLen = len(func.func_defaults) # number of keyword arguments validKwargs = validArgs[-kwargsLen:] # because kwargs are last return dict((key, value) for key, value in argsDict.iteritems() if key in validKwargs) 

你现在可以用已知的参数调用你的函数,但是提取了kwargs,例如:

 func(param1, param2, **getValidKwargs(func, kwargsDict)) 

这个假定func在其签名中不使用*args**kwargs魔法。

在Python 3.0中:

 >>> import inspect >>> import fileinput >>> print(inspect.getfullargspec(fileinput.input)) FullArgSpec(args=['files', 'inplace', 'backup', 'bufsize', 'mode', 'openhook'], varargs=None, varkw=None, defaults=(None, 0, '', 0, 'r', None), kwonlyargs=[], kwdefaults=None, annotations={}) 

扩展DzinX的答案:

 argnames = example.func_code.co_varnames[:func.func_code.co_argcount] args = dict((key, val) for key,val in d_args.iteritems() if key in argnames) example(**args) 

对于Python 3解决scheme,您可以根据您想要了解的参数types使用inspect.signature和filter。

以位置或关键字,仅关键字,var位置和var关键字参数作为示例函数:

 def spam(a, b=1, *args, c=2, **kwargs): print(a, b, args, c, kwargs) 

你可以为它创build一个签名对象:

 from inspect import signature sig = signature(spam) 

然后用列表理解过滤来找出你需要的细节:

 >>> # positional or keyword >>> [p.name for p in sig.parameters.values() if p.kind == p.POSITIONAL_OR_KEYWORD] ['a', 'b'] >>> # keyword only >>> [p.name for p in sig.parameters.values() if p.kind == p.KEYWORD_ONLY] ['c'] 

同样,对于p.VAR_POSITIONAL使用p.VAR_POSITIONAL和var关键字的var位置。

另外,可以通过检查p.default等于p.empty来为if检查是否存在缺省值。