获取函数参数的默认值?

sky*_*ler 52 python

对于这个功能

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

我希望,在函数外部,读取它的参数和附加的任何默认值.所以对于这个具体的例子,我想知道它name没有默认值(即它是必需的参数),这True是默认值should_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)
Run Code Online (Sandbox Code Playgroud)

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

mgi*_*son 87

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
    }
Run Code Online (Sandbox Code Playgroud)

Python2.x(旧答案)

args/defaults可以组合为:

import inspect
a = inspect.getargspec(eat_dog)
zip(a.args[-len(a.defaults):],a.defaults)
Run Code Online (Sandbox Code Playgroud)

以下a.args[-len(a.defaults):]是具有默认值的参数,显然a.defaults是相应的默认值.

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


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

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))
Run Code Online (Sandbox Code Playgroud)

来想一想:

    return dict(zip(reversed(args), reversed(defaults)))
Run Code Online (Sandbox Code Playgroud)

对一些人来说也会有所帮助.



Edd*_*man 12

对于那些寻找版本以通过mgilson 的答案获取特定默认参数的人。

value = signature(my_func).parameters['param_name'].default
Run Code Online (Sandbox Code Playgroud)

这是一个完整的工作版本,用 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
Run Code Online (Sandbox Code Playgroud)


Tad*_*eck 6

您可以使用inspect模块及其getargspec功能:

inspect.getargspec(func)

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

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


Chr*_*nds 6

根据您的需要,您可能不需要该inspect模块,因为您可以检查__defaults__函数的属性:

>>> eat_dog.__defaults__
(True,)
>>> eat_dog.__code__.co_argcount
2
>>> eat_dog.__code__.co_varnames
('name', 'should_digest')
>>> 
>>> eat_dog.__kwdefaults__
>>> eat_dog.__code__.co_kwonlyargcount
0 
Run Code Online (Sandbox Code Playgroud)