获取函数参数的默认值? [英] Get a function argument's default value?

查看:37
本文介绍了获取函数参数的默认值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于这个函数

defeat_dog(name, should_digest=True):打印吃了名为 %s 的狗.消化了吗?%" % (name, str(should_digest))

我想在函数外部读取它的参数和附加的任何默认值.所以对于这个特定的例子,我想知道 name 没有默认值(即它是一个必需的参数)并且 True 的默认值should_digest.

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

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

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

此外,我知道解决问题的请求宽恕"模型,但不幸的是,该错误的输出不会告诉我丢失参数的名称:

<预><代码>>>>吃狗()回溯(最近一次调用最后一次):文件<stdin>",第 1 行,在 <module> 中类型错误:eat_dog() 需要至少 1 个参数(给定 0)

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

解决方案

Python3.x

在 python3.x 世界中,您可能应该使用 签名对象:

导入检查def get_default_args(func):签名=inspect.signature(func)返回 {k: v.default对于 k, v 在 signature.parameters.items()如果 v.default 不是 inspect.Parameter.empty}

Python2.x(旧答案)

参数/默认值可以组合为:

导入检查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 返回一个 命名元组.早期版本返回一个常规元组,但相应地进行修改将非常容易.这是一个适用于旧(和新)版本的版本:

导入检查def get_default_args(func):"""返回输入函数的 arg_name:default_values 字典"""参数,可变参数,关键字,默认值 = inspect.getargspec(func)返回 dict(zip(args[-len(defaults):], defaults))

想一想:

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

也可以,并且对某些人来说可能更直观.

<小时>

For this function

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

I want to, external to the function, read its arguments and any default values attached. So for this specific example, I want to know that name has no default value (i.e. that it is a required argument) and that True is the default value for should_digest.

I'm aware of inspect.getargspec(), which does give me information about arguments and default values, but I see no connection between the two:

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

From this output how can I tell that True (in the defaults tuple) is the default value for should_digest?

Additionally, I'm aware of the "ask for forgiveness" model of approaching a problem, but unfortunately output from that error won't tell me the name of the missing argument:

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

To give context (why I want to do this), I'm exposing functions in a module over a JSON API. If the caller omits certain function arguments, I want to return a specific error that names the specific function argument that was omitted. If a client omits an argument, but there's a default provided in the function signature, I want to use that default.

解决方案

Python3.x

In a python3.x world, you should probably use a Signature object:

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 (old answer)

The args/defaults can be combined as:

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

Here a.args[-len(a.defaults):] are the arguments with defaults values and obviously a.defaults are the corresponding default values.

You could even pass the output of zip to the dict constructor and create a mapping suitable for keyword unpacking.


looking at the docs, this solution will only work on python2.6 or newer since I assume that inspect.getargspec returns a named tuple. Earlier versions returned a regular tuple, but it would be very easy to modify accordingly. Here's a version which works with older (and newer) versions:

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

Come to think of it:

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

would also work and may be more intuitive to some people.


这篇关于获取函数参数的默认值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆