获取函数参数的默认值?

时间:2012-09-27 17:40:08

标签: python

对于此功能

def eat_dog(name, should_digest=True):
    print "ate dog named %s. Digested, too? %" % (name, str(should_digest))

我希望在函数外部读取其参数和附加的任何默认值。因此,对于此特定示例,我想知道name没有默认值(即它是必需参数),Trueshould_digest的默认值。

我知道inspect.getargspec(),它确实提供了有关参数和默认值的信息,但我发现两者之间没有联系:

ArgSpec(args=['name', 'should_digest'], varargs=None, keywords=None, defaults=(True,))

从这个输出中我怎么知道True(在defaults元组中)是should_digest的默认值?

此外,我知道接近问题的“请求宽恕”模式,但不幸的是,该错误的输出不会告诉我缺少参数的名称:

>>> eat_dog()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: eat_dog() takes at least 1 argument (0 given)

为了给出上下文(为什么我要这样做),我通过JSON API公开模块中的函数。如果调用者省略了某些函数参数,我想返回一个特定的错误,该错误命名了省略的特定函数参数。如果客户端省略了参数,但函数签名中提供了默认值,我想使用该默认值。

6 个答案:

答案 0 :(得分:82)

Python3.x

在python3.x世界中,您应该使用Signature对象:

import inspect

def get_default_args(func):
    signature = inspect.signature(func)
    return {
        k: v.default
        for k, v in signature.parameters.items()
        if v.default is not inspect.Parameter.empty
    }

Python2.x(旧答案)

args / defaults可以合并为:

import inspect
a = inspect.getargspec(eat_dog)
zip(a.args[-len(a.defaults):],a.defaults)

此处a.args[-len(a.defaults):]是带有默认值的参数,显然a.defaults是相应的默认值。

您甚至可以将zip的输出传递给dict构造函数,并创建适合关键字解包的映射。


查看文档,这个解决方案只适用于python2.6或更新版本,因为我假设inspect.getargspec返回一个名为tuple 。早期版本返回了常规元组,但相应地修改它会非常容易。这是一个适用于较旧(和较新)版本的版本:

import inspect
def get_default_args(func):
    """
    returns a dictionary of arg_name:default_values for the input function
    """
    args, varargs, keywords, defaults = inspect.getargspec(func)
    return dict(zip(args[-len(defaults):], defaults))

来想一想:

    return dict(zip(reversed(args), reversed(defaults)))

也会有用,对某些人来说可能更直观。


答案 1 :(得分:6)

您可以将inspect模块与getargspec function

一起使用
  

inspect.getargspec(func)

     

获取Python函数参数的名称和默认值。返回tuple四件事:(args, varargs, keywords, defaults) args是参数名称列表(它可能包含嵌套列表)。 varargskeywords***参数或None的名称。如果没有默认参数, defaults是默认参数值None的元组;如果此元组包含n个元素,则它们对应于n中列出的最后args个元素。

有关如何检索参数名称及其默认值的确切代码,请参阅mgilson's answer

答案 2 :(得分:3)

根据实际需要,可能不需要'<b>This</b>\n" is "\n<b>a</b>\n" test "\n<b>string'模块,因为可以检查函数的</br>属性:

inspect

答案 3 :(得分:2)

对于那些希望通过mgilson's答案来获取特定默认参数的版本的用户。

    value = signature(my_func).parameters['param_name'].default

这是一个完整的工作版本,已在Python 3.8.2

中完成
from inspect import signature

def my_func(a, b, c, param_name='apple'):
    pass

value = signature(my_func).parameters['param_name'].default

print(value == 'apple') # True

答案 4 :(得分:1)

在python中,所有带有默认值的参数都在没有默认值的参数之后。因此,映射应从结束开始,直到您耗尽默认值列表。因此逻辑:

dict(zip(reversed(args), reversed(defaults)))

给出正确映射的默认值。

答案 5 :(得分:1)

处理仅限关键字的args(因为默认值和kwonlydefaults可以是None):

spec = inspect.getfullargspec(func)
defaults = dict(zip(spec.args[::-1], (spec.defaults or ())[::-1]))
defaults.update(spec.kwonlydefaults or {})