我是Python的新手。我正在写一个脚本,它将使用Runge-Kutta方法对一组常微分方程进行数值积分。由于龙格-库塔方法是一种有用的数学算法,因此我将其放在它自己的.py文件rk4.py中。
def rk4(x,dt):
k1=diff(x)*dt
k2=diff(x+k1/2)*dt
k3=diff(x+k2/2)*dt
k4=diff(x+k3)*dt
return x+(k1+2*k2+2*k3+k4)/6该方法需要知道用户正在处理的方程式集才能执行算法,因此它调用一个函数diff(x),该函数将为rk4找到工作所需的导数。由于方程式会因使用而改变,因此我希望在运行特定问题的脚本中定义diff()。在这种情况下,问题是水星的轨道,所以我写了mercury.py。(这不是它最终的样子,但为了弄清楚我在做什么,我对它进行了简化。)
from rk4 import rk4
import numpy as np
def diff(x):
return x
def mercury(u0,phi0,dphi):
x=np.array([u0,phi0])
dt=2
x=rk4(x,dt)
return x
mercury(1,1,2)当我运行mercury.py时,我得到一个错误:
File "PATH/mercury.py", line 10, in mercury
x=rk4(x,dt)
File "PATH/rk4.py", line 2, in rk4
k1=diff(x)*dt
NameError: global name 'diff' is not defined我认为这是因为diff()不是一个全局函数,当rk4运行时,它对diff一无所知。显然,rk4只是一小段代码,我可以把它塞进我当时正在使用的任何脚本中,但我认为龙格-库塔积分器是一个基本的数学工具,就像NumPy中定义的数组一样,所以让它成为一个在每个使用它的脚本中定义的函数是有意义的(可能有很多)。但是我也不能告诉rk4.py从特定的.py文件中导入特定的diff,因为这首先会破坏我想要的rk4的通用性。
有没有办法在像mercury.py这样的脚本中全局定义diff,这样当rk4被调用时,它就会知道diff?
发布于 2012-10-02 22:17:29
接受函数作为参数:
def rk4(diff, # accept an argument of the function to call
x, dt)
k1=diff(x)*dt
k2=diff(x+k1/2)*dt
k3=diff(x+k2/2)*dt
k4=diff(x+k3)*dt
return x+(k1+2*k2+2*k3+k4)/6然后,在调用rk4时,只需传入要执行的函数:
from rk4 import rk4
import numpy as np
def diff(x):
return x
def mercury(u0,phi0,dphi):
x=np.array([u0,phi0])
dt=2
x=rk4(diff, # here we send the function to rk4
x, dt)
return x
mercury(1,1,2)对于mercury来说,接受diff作为参数可能是个好主意,而不是从闭包(周围的代码)中获取它。然后,您必须像往常一样传递它--您在最后一行对mercury的调用应该是mercury(diff, 1, 1, 2)。
在Python中,函数是“一等公民”(几乎所有东西,包括类和模块),因为它们可以用作参数,可以保存在列表中,可以分配给名称空间中的名称,等等。
发布于 2012-10-02 22:22:58
在模块mercury.py中,diff已经是全局变量。但是为了在rk4.py中使用它,你需要像这样导入它:
from mercury import diff这就是对你问题的直接回答。
但是,按照@poorsod的建议将diff函数传递给rk4要优雅得多,而且还避免了mercury.py和rk4.py之间的循环依赖,所以我建议您这样做。
https://stackoverflow.com/questions/12691949
复制相似问题