我们如何检查函数是否在Python中返回多个值?

Too*_*one 4 python return-type return-value python-3.x

这个问题已经被问到,但我想问一些巧妙的不同.

我们如何确定python函数是否返回多个值,而不调用函数?有没有办法找到更像编译时而不是在运行时的东西?(我意识到python是一种解释语言)

以下是不可能的:

r = demo_function(data) # takes more than 5 minutes to run
if (not len(r) == 2) or (not isinstance(r, tuple)):
    raise ValueError("I was supposed to return EXACTLY two things")
Run Code Online (Sandbox Code Playgroud)

所以是:

try:
    i, j = demo_function(data)
    # I throw TypeError: 'int' object is not iterable
except ValueError:
    raise ValueError("Hey! I was expecting two values.")
except TypeError:
    s1 = "Hey! I was expecting two values."
    s2 = "Also, TypeError was thrown, not ValueError"
    raise ValueError(s1 + s2)
Run Code Online (Sandbox Code Playgroud)

以下类型的作品,但非常不优雅:

r = demo_function(extremely_pruned_down_toy_data) # runs fast
if len(r) != 2:
    raise ValueError("There are supposed to be two outputs")
# Now we run it for real
r = demo_function(data) # takes more than 5 minutes to run
Run Code Online (Sandbox Code Playgroud)

python中已经有一些工具可以做类似的事情.例如,我们可以找出一个类对象是否具有某个属性:

prop_str = 'property'
if not hasattr(obj, prop_str):
    raise ValueError("There is no attribute named" + prop_str + " NOOOOoooo! ")
Run Code Online (Sandbox Code Playgroud)

此外,我们可以找出一个函数有多少个INPUTS:

from inspect import signature

sig = signature(demo_function)
p = sig.parameters
if len(p)) != 2:
raise ValueError("The function is supposed to have 2 inputs, but it has" + str(p))
Run Code Online (Sandbox Code Playgroud)

我基本上想要以下内容:

p = nargout(demo_function)
if p != 2:
    raise ValueError("The function is supposed to have 2 outputs, but it has" + str(p))
Run Code Online (Sandbox Code Playgroud)

询问函数返回的是一个可以询问函数的最基本的问题之一.我很难找到它,这感觉很奇怪.

编辑:

juanpa.arrivillaga写道,

[...]从根本上说,这指出了一个更深层次的底层设计缺陷:为什么你有这样的功能,当你期望一个特定的长度时,它可以返回不同长度的容器?

好吧,让我解释一下.我有这样的事情:

def process_data(data_processor, data):
    x, y =  data_processor(data)
    return x, y
Run Code Online (Sandbox Code Playgroud)

process_data函数的前提条件是输入data_processor 必须返回两个项.因此,我想编写一些错误检查代码来强制执行前提条件.

def process_data(data_processor, data):
    # make sure data_processor returns exactly two things!
    verify_data_processor(data_processor)
    x, y =  data_processor(data)
    return x, y
Run Code Online (Sandbox Code Playgroud)

但是,看起来这并不容易.

jua*_*aga 5

函数实际上只有一个返回值.它可以返回tuple任何长度的容器,例如a .但是Python函数没有固有的方法来知道这样一个值的长度,Python过于动态了.实际上,通常,解释器不知道函数返回值的性质.但即使我们坚持只考虑返回容器的函数,请考虑以下函数:

def howmany(n):
    return n*('foo',)
Run Code Online (Sandbox Code Playgroud)

那么,应该nargout(howmany)返回什么?

而Python没有特殊情况是这样return x, y,也不应该,因为那样的话应该是什么行为时,返回的集装箱的长度不确定的,如return n*(1,)?不,是由调用者来处理返回容器的函数的情况,这是你已经说明过的一种方式.

从根本上说,这指向了一个更深层次的底层设计缺陷:为什么当你期望特定的长度时,你有能够返回不同长度容器的函数?