Can you list the keyword arguments a function receives?

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

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

如果 d _ args 结果中有值不被 example函数接受,那么 but就会失效。.例如,如果示例函数定义为 def example(kw2):

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

理想情况下,我会直接做

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

我可能只是从一个有效的关键字参数列表中过滤这个结果,但是我想知道: 有没有一种方法可以通过编程的方式列出特定函数所使用的关键字参数?

66760 次浏览

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

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

这是因为第一个 co_varnames始终是参数(接下来是局部变量,如上面示例中的 y)。

所以现在你可以有一个函数:

def get_valid_args(func, args_dict):
'''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 args_dict.iteritems()
if key in validArgs)

然后你可以像这样使用:

>>> func(**get_valid_args(func, args))

if you 只需要关键字参数 of a function, you can use the func_defaults attribute to extract them:

def get_valid_kwargs(func, args_dict):
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 args_dict.iteritems()
if key in validKwargs)

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

func(param1, param2, **get_valid_kwargs(func, kwargs_dict))

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

延伸 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)

比直接检查代码对象和计算变量好一点的是使用检查模块。

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

如果您想知道它是否可以通过一组特定的参数调用,那么您需要不指定默认参数的参数。这些可以通过以下途径获得:

def get_required_args(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.

然后,一个函数告诉你,你的特定结语中缺少了什么:

def missing_args(func, argdict):
return set(get_required_args(func)).difference(argdict)

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

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

因此,如果它是可调用的,那么一个完整的测试是:

def is_callable_with_args(func, argdict):
return not missing_args(func, argdict) and not invalid_args(func, argdict)

(This is good only as far as python's arg parsing. Any runtime checks for invalid values in kwargs obviously can't be detected.)

在 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={})

对于 Python3解决方案,您可以使用 inspect.signature并根据希望了解的 这种参数进行过滤。

以一个带有位置或关键字、仅关键字、 var 位置和 var 关键字参数的函数为例:

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

您可以为它创建一个签名对象:

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']

and, similarly, for var positionals using p.VAR_POSITIONAL and var keyword with VAR_KEYWORD.

此外,您可以在 if 中添加一个子句,通过检查 p.default是否等于 p.empty来检查默认值是否存在。

只要用这个函数名‘ myfun’就可以了:

myfun.__code__.co_varnames