在 Python 脚本中定义全局函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12691949/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Defining a global function in a Python script
提问by Dylan B
I'm new to Python. I am writing a script that will numerically integrate a set of ordinary differential equations using a Runge-Kutta method. Since the Runge-Kutta method is a useful mathematical algorithm, I've put it in its own .py file, rk4.py.
我是 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
The method needs to know the set of equations that the user is working with in order to perform the algorithm, so it calls a function diff(x)that will find give rk4 the derivatives it needs to work. Since the equations will change by use, I want diff() to be defined in the script that will run the particular problem. In this case the problem is the orbit of mercury, so I wrote mercury.py. (This isn't how it will look in the end, but I've simplified it for the sake of figuring out what I'm doing.)
该方法需要知道用户正在使用的方程组才能执行该算法,因此它调用一个函数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)
When I run mercury.py, I get an error:
当我运行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
I take it since diff()is not a global function, when rk4 runs it knows nothing about diff. Obviously rk4 is a small piece of code and I could just shove it into whatever script I'm using at the time, but I think a Runge-Kutta integrator is a fundamental mathematical tool, just like the array defined in NumPy, and so it makes sense to make it a function that is called rather one that is defined in every script that uses it (which may be many). But I also can't go telling rk4.py to import a particular diff from a particular .py file, because that ruins the generality of rk4 that I want in the first place.
我接受它,因为diff()它不是一个全局函数,当 rk4 运行时,它对 diff 一无所知。显然 rk4 是一小段代码,我可以把它塞进我当时使用的任何脚本中,但我认为 Runge-Kutta 积分器是一个基本的数学工具,就像在 NumPy 中定义的数组一样,所以它使它成为一个被调用的函数而不是在使用它的每个脚本中定义的函数(可能有很多)是有意义的。但我也不能告诉 rk4.py 从特定的 .py 文件导入特定的差异,因为这破坏了我首先想要的 rk4 的通用性。
Is there a way to define diff globally within a script like mercury.py so that when rk4 is called, it will know about diff?
有没有办法在像mercury.py这样的脚本中全局定义diff,这样当rk4被调用时,它就会知道diff?
采纳答案by Benjamin Hodgson
Accept the function as an argument:
接受函数作为参数:
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
Then, when you call rk4, simply pass in the function to be executed:
然后,当您调用 时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)
It might be a good idea for mercuryto accept diffas an argument too, rather than getting it from the closure (the surrounding code). You then have to pass it in as usual - your call to mercuryin the last line would read mercury(diff, 1, 1, 2).
mercury接受diff作为参数也可能是一个好主意,而不是从闭包(周围的代码)中获取它。然后你必须像往常一样传递它 - 你mercury在最后一行中的调用将读取mercury(diff, 1, 1, 2).
Functions are 'first-class citizens' in Python (as is nearly everything, including classes and modules), in the sense that they can be used as arguments, be held in lists, be assigned to names in namespaces, etc etc.
函数在 Python 中是“一等公民”(几乎所有东西,包括类和模块),因为它们可以用作参数、保存在列表中、分配给命名空间中的名称等。
回答by Lukas Graf
diffis already a global in the module mercury.py. But in order to use it in rk4.pyyou would need to import it like this:
diff已经是模块中的一个全局变量mercury.py。但是为了在其中使用它,rk4.py您需要像这样导入它:
from mercury import diff
That's the direct answer to your question.
这就是你问题的直接答案。
However, passing the difffunction to rk4as suggested by @poorsod is much more elegant and also avoids a circular dependency between mercury.pyand rk4.py, so I suggest you do it that way.
但是,按照@poorsod 的建议将diff函数传递给rk4更优雅,并且还避免了mercury.py和之间的循环依赖rk4.py,因此我建议您这样做。

