首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python脚本中定义全局函数

在Python脚本中定义全局函数
EN

Stack Overflow用户
提问于 2012-10-02 22:11:18
回答 2查看 36K关注 0票数 11

我是Python的新手。我正在写一个脚本,它将使用Runge-Kutta方法对一组常微分方程进行数值积分。由于龙格-库塔方法是一种有用的数学算法,因此我将其放在它自己的.py文件rk4.py中。

代码语言:javascript
复制
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。(这不是它最终的样子,但为了弄清楚我在做什么,我对它进行了简化。)

代码语言:javascript
复制
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时,我得到一个错误:

代码语言:javascript
复制
  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?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-10-02 22:17:29

接受函数作为参数:

代码语言:javascript
复制
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时,只需传入要执行的函数:

代码语言:javascript
复制
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中,函数是“一等公民”(几乎所有东西,包括类和模块),因为它们可以用作参数,可以保存在列表中,可以分配给名称空间中的名称,等等。

票数 11
EN

Stack Overflow用户

发布于 2012-10-02 22:22:58

在模块mercury.py中,diff已经是全局变量。但是为了在rk4.py中使用它,你需要像这样导入它:

代码语言:javascript
复制
from mercury import diff

这就是对你问题的直接回答。

但是,按照@poorsod的建议将diff函数传递给rk4要优雅得多,而且还避免了mercury.pyrk4.py之间的循环依赖,所以我建议您这样做。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12691949

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档