科学python中的最佳多重返回值

use*_*929 4 python numpy ipython scipy

我使用scipy/numpy代替matlab研究代码.有一个缺陷,我经常遇到.我找到了一种解决方案,但想要检查最佳实践和更好的解决方案.想象一下一些数学优化:

def calculation (data, max_it=10000, tol = 1e-5):
    k = 0
    rmse = np.inf 
    while k < max_it and rmse > tol:
        #calc and modify data - rmse becomes smaller in each iteration
        k += 1
    return data
Run Code Online (Sandbox Code Playgroud)

它运行正常,我将它嵌入到我的代码中,在多个位置,例如:

 import module
 d = module.calculation (data)
Run Code Online (Sandbox Code Playgroud)

但有时我想检查更多的见解并需要多个返回值.如果我只是附加多个返回值,我必须修改其他代码并解压缩第一个返回值.这是少数情况之一,我更喜欢matlab scipy.在matlab中,只评估第一个返回值,除非你明确要求其余的.

所以我的matlab-like(=最佳)多个返回值的解决方案是[模块]的全局变量

def calculation (data, max_it=10000, tol = 1e-5):
    global k
    global rmse
    k = 0
    rmse = np.inf 
    while k < max_it and rmse > tol:
        #calc and modify data - rmse becomes smaller in each iteration
        k += 1
    return data
Run Code Online (Sandbox Code Playgroud)

我的函数调用工作而不进行修改,如果我想在ipython中验证某些内容,请设置一些变量全局重载(模块)并使用module.rmse检查洞察力.

但我也可以从一开始就想象出一个OO-aproach,或者使用pdb,或者使用其他的ipython魔法

unu*_*tbu 7

您可以指定info=True在调用时希望使用参数返回更多信息calculation.这是np.unique(带有它return_inversereturn_index参数)和scipy.optimize.leastsq(带有full_output参数)的方法:

def calculation(data, max_it=10000, tol = 1e-5, info=False):
    k = 0
    rmse = np.inf 
    while k < max_it and rmse > tol:
        #calc and modify data - rmse becomes smaller in each iteration
        k += 1
    if info:
        return data, k, rmse
    else:
        return data
Run Code Online (Sandbox Code Playgroud)

或者,您可以在calculation函数上分配其他属性:

def calculation(data, max_it=10000, tol = 1e-5):
    k = 0
    rmse = np.inf 
    while k < max_it and rmse > tol:
        #calc and modify data - rmse becomes smaller in each iteration
        k += 1
    calculation.k = k
    calculation.rmse = rmse
    return data
Run Code Online (Sandbox Code Playgroud)

然后可以访问添加的信息

import module
d = module.calculation(data)
rmse = module.calculation.rmse
Run Code Online (Sandbox Code Playgroud)

请注意,如果calculation从多个线程并发运行,后一种方法将无法正常工作...

在CPython中(由于GIL),在任何给定时间只能执行一个线程,因此calculation在多个线程中运行几乎没有吸引力.但谁知道呢?可能存在一些需要在小规模上使用线程的情况,例如可能在GUI中.在那里,访问calculation.kcalculation.rmse可能返回不正确的值.

而且,Python的Zen说,"明确比隐含更好".

所以我会推荐第一种方法.