Nik*_*Nik 21 python multiple-variable-return
Python在MATLAB中是否有任何等效的nargout?如果我们想保持返回参数的数量灵活,我发现nargout是一种非常简洁的方法.有没有办法可以找出已经请求了多少输出参数?像下面的伪python代码:
def var_returns_func(a):
"""
a is a 1D numpy array
"""
if nargout==1: return a.sum()
elif nargout==2: return a.sum(),a.std()
Run Code Online (Sandbox Code Playgroud)
因此,如果我将此函数称为mean = var_returns_func(someNumPyarray),则应返回单个值.但如果我把它称为mean,std = var_returns_func(someNumPyarray),它应该返回2个值.
是否有Pythonic方式这样做?还是一个黑客的方式?
Bre*_*arn 19
该函数无法知道返回值将要执行的操作,因此无法知道需要多少.你可以做的是nargout作为参数传递给你的函数并使用它来决定返回什么:
def f(a, nargout=1):
if nargout == 1:
return "one value"
elif nargout == 2:
return "two", "values"
else:
raise ValueError, "Invalid nargout!"
Run Code Online (Sandbox Code Playgroud)
这是作为Python哲学的"显性优于隐式"的示例.如果你想要两个参数,你必须明确地说你想要两个参数.在Python中不鼓励根据展望未来来看看将要对结果做些什么进行隐式决定.这是完全可能的,a = f(x)并希望得到一个双元素元组.
像你这样的例子,有很多更好的方法.一个是做mean, std = a.mean(), a.std(),或者更普遍x, y = someFunc(a), otherFunc(a).如果通常需要这种特定的值组合,并且您不希望复制的两个操作共享一些昂贵的计算,那么创建一个可以清楚地返回两者并执行的第三个函数x, y = funcThatReturnsTwoThings(a).所有这些都是明确的方法,如果他们做不同的事情,保持功能分开.
我不能nargout在MATLAB中代言,因为我不知道它,我无法想象它应该如何正确使用.但是,您可能希望将视图更改为Python函数(或方法)的实际功能.
实际上,Python总是返回一个值.或者它是None,或者它是某个特定类型的单个值,或者它是该tuple类型的单个对象.
如果没有return命令,None则函数体结束时函数返回.它就像你return在body return None的末尾或者body的末尾显式地没有参数一样.
如果您使用return None(None可以存储在变量中)或return没有参数,None则返回调用者.
如果您return single,该single对象将返回给调用者.
如果你return v1, v2, v3,你实际上返回一个元组(v1, v2, v3).它只是一个语法糖,你不需要写括号.
在result1, result2, result3 = f()的情况下是另一种语法糖.该f()返回的元组和它的元素自动提取给定的变量.你实际上做了:
result1, result2, result3 = (v1, v2, v3)
Run Code Online (Sandbox Code Playgroud)
要么
t = f() # where t is the (v1, v2, v3)
result1, result2, result3 = t
Run Code Online (Sandbox Code Playgroud)
实际上,Python不允许像其他语言中那样定义输出参数.您可以考虑传递参数对象的地址,如果传递的对象允许修改,您可以修改它.但是,例如,你永远无法将新结果传递给最初具有None值的传递参数.你不能通过函数的输出参数来分配Python变量 - 没有像Python那样的机制.
从函数内部返回新创建的值(对象)的唯一自然和直接方法是使用该return命令.但是,Python函数不会限制您可以返回多少个参数.(好吧,总是一个单独的,如果它是一个元组,可以稍后分解为元素.)
如果你想在调用者代码来测试什么实际返回,您可以编写自己的函数,它的情况下,一些特别的东西在那里被送回以下值:None,single,一些长度的元组(len(t)可以用来获取元素的数量在返回的元组中t).您的函数还可以测试single每个元组元素的类型或相应的工作.
我倾向于做的是让我的函数返回所有内容(作为元组的元素),然后只解压我需要的内容:
def my_func():
# do stuff...
return mean, stddev, otherstat, a, b
mu, sig, _, a, _ = myfunc()
Run Code Online (Sandbox Code Playgroud)
这里我返回所有内容,但仅将第一个、第二个和第四个变量分配给我将在调用范围中使用的变量。该_变量是一个一次性变量,用作我不想要/不需要的变量的占位符。
我有一个奇怪的想法...
def nargout():
import traceback
callInfo = traceback.extract_stack()
callLine = str(callInfo[-3].line)
split_equal = callLine.split('=')
split_comma = split_equal[0].split(',')
return len(split_comma)
def fun():
this = nargout()
if this == 1:
return 3
else:
return 3, 4
a = fun()
a, b = fun()
Run Code Online (Sandbox Code Playgroud)
我现在真的很想念 Matlab :D
改进方法:
def nargout(*args):
import traceback
callInfo = traceback.extract_stack()
callLine = str(callInfo[-3].line)
split_equal = callLine.split('=')
split_comma = split_equal[0].split(',')
num = len(split_comma)
return args[0:num] if num > 1 else args[0]
def fun(nparray):
return nargout(np.mean(nparray), np.std(nparray))
arr = np.array([3, 4, 5])
mean = fun(arr)
mean, std = fun(arr)
Run Code Online (Sandbox Code Playgroud)