【问题标题】:Introspect function to determine which argument unpacking (positional or keyword) was used内省函数以确定使用了哪个参数解包(位置或关键字)
【发布时间】:2014-01-29 00:38:28
【问题描述】:

我正在寻找一种方法来确定某些参数是否用于解包,我发现了这个:

>>> def func_has_positional_args(func):
    std_args = func.func_code.co_argcount
    wildcard_args = len(func.func_code.co_varnames) - std_args
    if wildcard_args == 2:
        return True  # yes, has both positional and keyword args
    elif wildcard_args == 0:
        return False  # has neither positional, nor keyword args
    else:
        raise NotImplementedError('Unable to tell')


>>> func_has_keyword_args = func_has_positional_args
>>> def test1(a, b, *args, **kwargs): pass

>>> func_has_positional_args(test1), func_has_keyword_args(test1)
(True, True)
>>> def test2(a, b): pass

>>> func_has_positional_args(test2), func_has_keyword_args(test2)
(False, False)
>>> def test3(a, b, *args): pass

>>> func_has_positional_args(test3)

Traceback (most recent call last):
  File "<pyshell#52>", line 1, in <module>
    func_has_positional_args(test3)
  File "<pyshell#41>", line 9, in func_has_positional_args
    raise NotImplementedError('Unable to tell')
NotImplementedError: Unable to tell

所以我可以判断,如果没有位置参数,也没有关键字参数解包。我也可以判断两者是否都有,但如果只有一个“通配符”,我无法区分实现了哪个“通配符”类型参数。

您能帮我实现以下结果吗?

# Already satisfied with above code:
assert func_has_positional_args(test1) == True
assert func_has_keyword_args(test1) == True
assert func_has_positional_args(test2) == False
assert func_has_keyword_args(test2) == False

# Missing functionality (tests are failing):
assert func_has_positional_args(test3) == True
assert func_has_keyword_args(test3) == False

另外,Python 3 对此功能或其行为有什么改变吗?

【问题讨论】:

  • ...我不确定我是否真的密切关注这个,但你不是在寻找inspect.getargspec 吗?你所做的有什么不同?
  • @mgilson:是的,靶心;)似乎我太专注于查找函数属性而不是查看inspect 模块...您愿意将其发布为答案吗?

标签: python python-3.x introspection argument-passing keyword-argument


【解决方案1】:

正如 mgilson 所说,使用 inspect.getargspec(在 Python 3.x 中更适合使用 inspect.getfullargspec)。

import inspect

def func_has_positional_args(func):
    spec = inspect.getfullargspec(func)
    return bool(spec.varargs) # varargs: name of the * argument or None
def func_has_keyword_args(func):
    spec = inspect.getfullargspec(func)
    return bool(spec.varkw)   # varkw: name of the ** argument or None

例子:

>>> def test1(a, b, *args, **kwargs): pass
...
>>> def test2(a, b): pass
...
>>> def test3(a, b, *args): pass
...
>>> func_has_positional_args(test1)
True
>>> func_has_keyword_args(test1)
True
>>> func_has_positional_args(test2)
False
>>> func_has_keyword_args(test2)
False
>>> func_has_positional_args(test3)
True
>>> func_has_keyword_args(test3)
False

【讨论】:

  • 谢谢,所以编写 Python 2.x + 3.x 兼容代码的首选方法是在导入 inspect 期间实际执行此操作,对吗?我没有找到six这个功能的模块支持。
  • @Tadeck,如果您想要同时在 Python 2、3 中运行的代码,请使用 inspect.getargspec。 (将varkw 替换为keywords)。
  • @Tadeck, inspect.getargspec 根据文档已弃用。但即使在Python 3.4 中,getargspec 仍然存在。
猜你喜欢
  • 2018-09-15
  • 1970-01-01
  • 2023-03-31
  • 2019-04-23
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2021-07-08
相关资源
最近更新 更多