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

2024-10-02 14:20:06 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

这工作得很好,但是如果d}args dict中的值不被example函数接受,那么它显然会死掉。。例如,如果示例函数定义为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)

我可能只是从一个有效的关键字参数列表中筛选dict,但我想知道:是否有方法以编程方式列出特定函数采用的关键字参数?


Tags: key函数参数exampleargs关键字parseddict
3条回答

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

使用inspect模块比直接检查代码对象并计算变量要好一点。

>>> 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.

然后,一个函数可以告诉您在特定的dict中缺少什么:

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)

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

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

(这只适用于python的arg解析。显然,无法检测到任何运行时检查kwargs中的无效值。)

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

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

现在可以用已知的参数调用函数,但提取的参数为,例如:

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

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

相关问题 更多 >