我是Python的新手,并且有一个特定于问题的问题,关于如何访问函数中定义的非返回变量。
我在Python中使用的分析包需要用户定义的函数作为输入。它期望以特定方式定义的函数返回单个输出。但是,出于诊断目的,我希望在调用之后从该函数获得多个输出(例如,在分析的特定阶段产生诊断图)。但是,我无法修改函数以返回多个输出(除非我修改分析代码调用的每个实例 - 不实用);这会导致错误。
例如,在下面的示例中,用户定义的函数返回f1 + f2,但出于诊断目的,请说我想知道f1和f2分别是什么:
def my2dfunction(x,y,theta):
'''x and y are 1-d arrays of len(x)==len(y)
theta is an array of 5 model parameters '''
f1=theta[0]+theta[1]*x+theta[2]*x**2
f2=theta[3]*y+theta[4]*y**2
return f1+f2
在这个网站上进行研究我提出了两种可能的解决方案:
创建一个包含最新函数调用中f1和f2值的全局变量,我可以随时访问该函数:
live_diagnostic_info={'f1':0, 'f2':0}
def my2dfunction(x,y,theta):
f1=theta[0]+theta[1]*x+theta[2]*x**2
f2=theta[3]*y+theta[4]*y**2
global live_diagnostic_info={'f1':f1, 'f2':f2}
return f1+f2
定义与第一个具有多个返回值的第二个函数相同的函数,仅在需要诊断信息的实例中调用。
def my2dfunction_extra(x,y,theta):
f1=theta[0]+theta[1]*x+theta[2]*x**2
f2=theta[3]*y+theta[4]*y**2
return f1+f2,f1,f2
我认为两者都可以用于我的目的,但我想知道是否有另一种方法可以从Python中的函数传递非返回变量。 (例如,我在IDL中进行了大量编码,其中可以通过关键字传递额外信息,而无需修改return语句,并且想知道如果存在Python等价物的话。)
答案 0 :(得分:0)
为函数
添加可选参数def my2dfunction(x,y,theta, local_debug=None):
'''x and y are 1-d arrays of len(x)==len(y)
theta is an array of 5 model parameters '''
f1=theta[0]+theta[1]*x+theta[2]*x**2
f2=theta[3]*y+theta[4]*y**2
if local_debug is not None:
local_debug["f1"] = f1
local_debug["f2"] = f2
return f1+f2
然后用字典调用它
local_data = {}
my2dfunction(x,y,theta, local_data)
返回时你有dict中的信息。旧的客户端代码不会在返回或提供的输入值中受到影响。
如果您想要保存它们而不管是谁调用例程,您可以执行以下操作。按如下方式创建例程
def my2dfunction(x,y,theta, local_debug={}):
'''x and y are 1-d arrays of len(x)==len(y)
theta is an array of 5 model parameters '''
f1=theta[0]+theta[1]*x+theta[2]*x**2
f2=theta[3]*y+theta[4]*y**2
local_debug["f1"] = f1
local_debug["f2"] = f2
return f1+f2
然后你可以从外面访问local_debug字典
python3: my2dfunction.__defaults__[0]
python2: my2dfunction.func_defaults[0]
请记住,将mutable(例如列表,词典等)作为默认值是python faux pas,但在这种情况下有动机。
答案 1 :(得分:0)
您可以编写装饰器,因此您无需为第二个解决方案复制粘贴任何内容:
def return_first(f):
return lambda *args, **kwargs: f(*args, **kwargs)[0]
return_first
接受一个函数,并返回相同的函数,但只返回第一个值。
def my2dfunction_extra(x,y,theta):
f1=theta[0]+theta[1]*x+theta[2]*x**2
f2=theta[3]*y+theta[4]*y**2
return f1+f2,f1,f2
my2dfunction = return_first(my2dfunction_extra)