You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免重复代码处理异常、未定义变量及特定比较逻辑

解决重复异常/条件处理代码的小技巧(无需新函数)

嘿,我完全懂你这种重复写相同处理代码的烦躁——不仅代码冗余,后期改一处就得改两处,很容易出错。针对你不想定义新函数的需求,咱们可以用标志位统一触发的方式,把所有需要走错误处理的情况都导向同一段代码,下面结合你的代码给你具体说明:

核心思路

用一个布尔变量(比如fit_success)来标记拟合是否成功,不管是抛出ValueError/RuntimeError异常,还是拟合参数不满足条件的情况,都把这个变量设为False。最后只需要判断这个变量的值,执行一次统一的处理逻辑就行,不用重复写两遍代码。

修改后的代码示例

if fitfn not in ['gauss','lorentz']: 
    raise IOError("Fitting function name must be 'lorentz' or 'gauss'")

cubedims = np.shape(cube)
frames = np.array([(n,w) for n,w in enumerate(wvl) if (lc-0.2 < w < lc+0.2)])
inds,wls = np.transpose(frames)

# 初始化各种结果数组
fdencube = np.zeros((cubedims[1], cubedims[2]))
fduncube = np.zeros((cubedims[1], cubedims[2]))
spindex = np.zeros((cubedims[1], cubedims[2]))
spundex = np.zeros((cubedims[1], cubedims[2]))
lincube = np.zeros((len(frames), cubedims[1], cubedims[2]))
elincube = np.zeros((len(frames), cubedims[1], cubedims[2]))
concube = np.zeros((cubedims))
econcube = np.zeros((cubedims))

for x in xrange(cubedims[1]):
    for y in xrange(cubedims[2]):
        spec = cube[:,x,y]
        uspec = ecube[:,x,y]
        fit_success = True  # 初始化标志位为成功
        
        try:
            p, pcov = curvf(globals()[fitfn], wvl[~np.isnan(spec)], spec[~np.isnan(spec)],
                           sigma=uspec[~np.isnan(spec)], 
                           bounds = [[0.01, min(wvl), np.mean(wvl[1:]-wvl[:-1]), -10, 0.], 
                                     [50., max(wvl), 0.4, 10, 10.0]])
            fwhm = 2*abs(p[2]) if fitfn=='lorentz' else p[2]*np.sqrt(8*np.log(2))
            
            # 检查初始拟合参数是否符合要求
            if not (fwhm < 0.16 and (lc-0.05 < p[1] < lc+0.05) and 'pcov' in globals()):
                fit_success = False
                # 尝试分段拟合
                try:
                    s = spec[~inds.astype(int)]
                    u = uspec[~inds.astype(int)]
                    q, qcov = curvf(lreg, wls[~np.isnan(s)], s[~np.isnan(s)], 
                                   sigma=u[~np.isnan(s)],
                                   bounds = [[-10,0.], [10,10.0]])
                    r, rcov = curvf(globals()[fitfn], wvl[inds.astype(int)], spec[inds.astype(int)], 
                                   sigma=uspec[inds.astype(int)],
                                   bounds = [[0.01, min(wvl), np.mean(wvl[1:]-wvl[:-1]), -10, 0.], 
                                             [50., max(wvl), 0.4, 10, 10.0]])
                    fwhmr = 2*abs(r[2]) if fitfn=='lorentz' else r[2]*np.sqrt(8*np.log(2))
                    
                    # 检查分段拟合参数是否符合要求
                    if (fwhmr < 0.16 and (lc-0.05 < r[1] < lc+0.05) and 'rcov' in globals()):
                        # 分段拟合成功,更新结果
                        stdr = np.sqrt(np.diag(rcov))
                        stdq = np.sqrt(np.diag(qcov))
                        lvw = gauss(wvl, r[0], r[1], r[2], 0, 0)
                        concube[:,x,y] = spec - lvw
                        econcube[:,x,y] = np.sqrt(uspec**2 + stdr[0]**2 + stdr[1]**2 + stdr[2]**2)
                        cvw = q[0]*frames[:,1] + q[1]
                        lincube[:,x,y] = spec[inds.astype(int)] - cvw
                        elincube[:,x,y] = np.sqrt(uspec[inds.astype(int)]**2 + stdq[-2]**2 + stdq[-1]**2)
                        spindex[x,y] = q[0]
                        spundex[x,y] = stdq
                        fdencube[x,y] = r[0]
                        fduncube[x,y] = stdr[0]
                        fit_success = True  # 分段拟合成功,重置标志位
                    else:
                        fit_success = False
                except (ValueError, RuntimeError):
                    fit_success = False
            else:
                # 初始拟合成功,更新结果
                stdp = np.sqrt(np.diag(pcov))
                cvw = p[-2]*frames[:,1] + p[-1]
                lincube[:,x,y] = spec[inds.astype(int)] - cvw
                elincube[:,x,y] = np.sqrt(uspec[inds.astype(int)]**2 + stdp[-2]**2 + stdp[-1]**2)
                lvw = gauss(wvl, p[0], p[1], p[2], 0, 0)
                concube[:,x,y] = spec - lvw
                econcube[:,x,y] = np.sqrt(uspec**2 + stdp[0]**2 + stdp[1]**2 + stdp[2]**2)
                spindex[x,y] = p[-2]
                spundex[x,y] = stdp[-2]
                fdencube[x,y] = p[0]
                fduncube[x,y] = stdp[0]
        except (ValueError, RuntimeError):
            fit_success = False
        
        # 统一处理所有拟合失败的情况
        if not fit_success:
            fdencube[x,y] = np.NaN
            fduncube[x,y] = np.NaN
            lincube[:,x,y] = np.NaN
            elincube[:,x,y] = np.NaN
            try:
                q, qcov = curvf(lreg, wvl[~np.isnan(spec)], spec[~np.isnan(spec)], 
                               sigma=uspec[~np.isnan(spec)],
                               bounds = [[-10,0.], [10,10.0]])
                if 'qcov' in globals():
                    concube[:,x,y] = spec
                    econcube[:,x,y] = uspec
                    spindex[x,y] = q[0]
                    spundex[x,y] = np.sqrt(np.diag(qcov))[0]
                else:
                    concube[:,x,y] = spec
                    econcube[:,x,y] = uspec
                    spindex[x,y] = q[0]
                    spundex[x,y] = np.NaN
            except (ValueError, RuntimeError):
                print('fit failed')
                concube[:,x,y] = spec
                econcube[:,x,y] = uspec
                spindex[x,y] = np.NaN
                spundex[x,y] = np.NaN

为什么这样有效?

  • 所有可能导致失败的场景(初始拟合异常、初始参数不合格、分段拟合异常、分段参数不合格)都会把fit_success设为False
  • 最后只需要执行一次失败处理逻辑,不用重复编写相同的代码块
  • 代码结构更清晰,后期修改处理逻辑只需要改一处即可

另外,虽然你不想定义新函数,但其实可以把失败处理逻辑封装成一个小型的嵌套函数(比如在for循环里定义),这样代码会更整洁,不过标志位的方式已经完全满足你的需求啦。

内容的提问来源于stack exchange,提问作者ColorOutOfSpace

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:08:30