python - 在 Python 脚本中定义全局函数

标签 python function python-2.7 global

我是 Python 新手。我正在编写一个脚本,它将使用 Runge-Kutta 方法对一组常微分方程进行数值积分。由于 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 是一小段代码,我可以将它推到我当时使用的任何脚本中,但我认为 Runge-Kutta 积分器是一种基本的数学工具,就像 NumPy 中定义的数组一样,所以它使它成为一个被调用的函数而不是在使用它的每个脚本(可能有很多)中定义的函数是有意义的。但我也不能告诉 rk4.py 从特定的 .py 文件导入特定的差异,因为这破坏了我一开始想要的 rk4 的通用性。

有没有办法在像 mercury.py 这样的脚本中全局定义 diff,以便在调用 rk4 时,它会知道 diff?

最佳答案

接受函数作为参数:

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 中的“一等公民”(几乎所有东西,包括类和模块),因为它们可以用作参数、保存在列表中、分配给 namespace 中的名称等等.

关于python - 在 Python 脚本中定义全局函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12691949/

相关文章:

python - 在远程机器上递归执行本地定义的 python 脚本

python - 我如何在普通浏览器中使用 selenium

javascript - jQuery 监听器点击不起作用

c - 如何在 C 中封装这样的函数?

python - 在 python 中仅连接带空格的行

mysql - Django、MySQL;加载 MySQLdb 模块时出错

python - flask /红移 : Avoid running same query in Flask app

python - 带有 Scrapy 子类初始化错误的动态蜘蛛生成

python - 值错误: invalid literal for int() with base 10: '–20'

javascript - 函数调用和关键字 'this' 之间有什么关系?