在Python函数内调用外部函数时出现UnboundLocalError求助
问题分析与修复方案
错误原因
在SM函数中,第33行的f, fp, fpp = sol.y语句会让Python将f识别为局部变量,但第32行调用solve_ivp(f, ...)时,这个局部的f还未被赋值,同时全局定义的函数f被局部变量名遮蔽,导致报错。
另外还有两处逻辑问题:
SM函数接收的参数fpp未被使用,始终调用全局的y0,不符合函数设计意图- 调用
solve_ivp时未指定t_eval,返回的解点数量不确定,后续绘图可能出现异常
修复后的代码
import numpy as np from scipy.integrate import solve_ivp import matplotlib.pyplot as plt ethaf = 10 # final value def f(t, r): f_val, fp, fpp = r # 变量名改为f_val,避免与函数名f混淆 dfdn = fp dfpdn = fpp dfppdn = -0.5 * f_val * fpp return dfdn, dfpdn, dfppdn # 单次求解测试用的初始猜测 initial_fpp = 0.4 y0_test = [0, 0, initial_fpp] t = np.linspace(0, ethaf, 101) sol_test = solve_ivp(f, (0, ethaf), y0_test, t_eval=t) def SM(input_fpp): # 使用传入的参数构造初始条件 y0 = [0, 0, input_fpp] # 指定t_eval确保每次求解返回的解点数一致 sol = solve_ivp(f, (0, ethaf), y0, t_eval=t, vectorized=True) # 重命名解变量,避免遮蔽全局函数f f_sol, fp_sol, fpp_sol = sol.y # 返回最终时刻的fp值(可根据需求调整返回位置) return fp_sol[-1] # 生成测试的fpp序列 fpp_range = np.linspace(0, 0.5, 500) # 批量计算SM结果 sm_results = [SM(fpp) for fpp in fpp_range] plt.plot(fpp_range, sm_results) plt.grid(linewidth=0.8, linestyle='--', alpha=0.6) plt.show()
关键修复点
- 重命名和解相关的变量(如
f_val、f_sol),避免与全局函数f重名,彻底消除变量遮蔽问题 - 在
SM函数中使用传入的input_fpp参数构造初始条件,实现函数的预期功能 - 调用
solve_ivp时指定t_eval,确保每次求解返回的解点数一致,保障绘图正常 - 用列表推导式批量处理
fpp_range,适配当前SM函数的单值输入逻辑
内容的提问来源于stack exchange,提问作者Matias Quintana
相关产品推荐
相关产品推荐

