这个问题是already asked,但我想问一些微妙的不同。
我们如何确定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")
所以:
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)
以下类型的作品,但非常不优雅:
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
python中已经有类似的工具。例如,我们可以找出一个类对象是否具有某个属性:
prop_str = 'property'
if not hasattr(obj, prop_str):
raise ValueError("There is no attribute named" + prop_str + " NOOOOoooo! ")
另外,我们可以找出一个函数有多少 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))
我基本上想要以下内容:
p = nargout(demo_function)
if p != 2:
raise ValueError("The function is supposed to have 2 outputs, but it has" + str(p))
询问函数返回的内容是人们可以询问函数的最基本的问题之一。我很难发现,感觉真的很奇怪。
juanpa.arrivillaga写道,
从根本上说,这指出了一个更深层次的底层设计缺陷:为什么你有能够在预期特定长度时返回不同长度容器的函数?好吧,让我解释一下。我有这样的事情:
def process_data(data_processor, data):
x, y = data_processor(data)
return x, y
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
然而,看起来这并不容易。
答案 0 :(得分:5)
功能实际上只有单一返回值。它可以返回任何长度的容器,例如tuple
。但是Python函数没有固有的方法来知道这样一个值的长度,Python过于动态了。实际上,通常,解释器不知道函数返回值的性质。但即使我们坚持只考虑返回容器的函数,请考虑以下函数:
def howmany(n):
return n*('foo',)
那么nargout(howmany)
应该返回什么?
python不像return x, y
这样的特殊情况,也不应该这样,因为当返回的容器的长度不确定时,应该是什么行为,例如{{1 }}?不,是由调用者来处理返回容器的函数的情况,这是你已经说明过的一种方式。
从根本上说,这指出了一个更深层次的底层设计缺陷:为什么你有预期特定长度的函数可以返回不同长度的容器?