Python:访问未返回的函数中定义的变量

时间:2014-07-26 21:17:01

标签: python

我是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

在这个网站上进行研究我提出了两种可能的解决方案:

  1. 创建一个包含最新函数调用中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
    
  2. 定义与第一个具有多个返回值的第二个函数相同的函数,仅在需要诊断信息的实例中调用。

    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
    
  3. 我认为两者都可以用于我的目的,但我想知道是否有另一种方法可以从Python中的函数传递非返回变量。 (例如,我在IDL中进行了大量编码,其中可以通过关键字传递额外信息,而无需修改return语句,并且想知道如果存在Python等价物的话。)

2 个答案:

答案 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)