获取函数的返回元素

时间:2018-01-21 08:29:13

标签: python python-3.x return introspection

有没有办法内省和获取函数的返回值。 例如

def foo():
    x = 10
    y = 20
    return x,y 

我正在寻找一种方法,将返回元素xy视为list。有干净的方法吗?

注意:

我不是在寻找返回元素的值。只是它们的名称和数量。

2 个答案:

答案 0 :(得分:3)

这通常是不可能的。考虑一下这个功能:

def foo(x, y):
    if x < y:
        return x
    else:
        return x, y

这里我们有一个可以有条件地返回1个值或2个值(具有不同名称)的函数。

如果您的函数有类型注释,那么您可以使用inspect.getfullargspec获取返回类型:

def foo(x: int) -> int:
    return x + 2

inspect.getfullargspec(foo).annotations['return']

返回

int

即。您指定函数将返回的类型。

注意:因为它们已修复,可能使用相同的方法获取函数参数的名称/默认值。即inspect.getfullargspec(foo).args会返回['x']

答案 1 :(得分:0)

一些ast转换应该会让你到那里。一个天真的实现可以这样做:

import inspect
import ast 

def get_return_ids(f):
    def get_ids(elt):
        """Extract identifiers if present. If not return None"""
        if isinstance(elt, (ast.Tuple, )):
            # For tuple get id of each item if item is a Name
            return [x.id for x in elt.elts if isinstance(x, (ast.Name, ))]
        if isinstance(elt, (ast.Name, )):
            return [elt.id]

    # Get source and parse AST
    (tree, ) = ast.parse(inspect.getsource(f)).body

    # Find all return statements
    rs = [
        node for node in ast.walk(tree) if isinstance(node, (ast.Return, ))
    ]

    return [get_ids(r.value) for r in rs]

使用示例:

>>> get_return_ids(foo)
[['x', 'y']]

功能更复杂(借用Alex's answer):

>>> def bar(x, y):
...     if x < y:
...         return x
...     else:
...         return x, y
...     
>>> get_return_ids(bar)
[['x'], ['x', 'y']]

在目前的形式中,它仅支持一小部分场景,但如果需要,可以扩展它。