Python中的全局变量通过模块/文件导入

时间:2017-09-29 06:31:23

标签: python scope

问题

我试图找到一种不那么笨重的方式来使用(或完成类似的)全局变量。现在我将所有全局变量放在 g.py 文件中,因此我使用g.var访问它们。

我希望在我的代码中使用var代替g.var,因为我觉得它看起来更干净。

详情

我现在有3个文件:

  • main.py:解决PDE的小代码
  • functions.py:定义应用边界条件的函数的文件
  • g.py:一个文件,其中包含在调用functions.py函数时修改的变量

g.py

import numpy as np
# variables
ap  = np.float64(0.0)
awx = np.float64(0.0)
aex = np.float64(0.0)
rhs = np.float64(0.0)

functions.py

import g

def bc_Neumann(i,m,nx):
    m[0]=int(i); m[1]=int(i-1); m[2]=int(i+1);
    if i==0:
        m[1]=nx-1
        g.ap=g.ap+g.awx
        g.awx=0.0
    if i==nx-1:
        m[2]=0
        g.ap=g.ap+g.aex
        g.aex=0.0
    return m

main.py在某个时候调用bc_Neumann()

是否有更好的方式来访问g.apg.awx等?我想将这些全局变量引用为apawx等等。

3 个答案:

答案 0 :(得分:1)

可以直接导入变量,即:

from g import ap, awx, aex, rhs

然后在函数中将它们声明为全局变量(否则它们被认为是本地变量,并且在重新绑定它们时会得到UnboundLocalError):

def bc_Neumann(i,m,nx):
    global ap, awx, aex, rhs
    # your code here

但是当您重新绑定g.apg.awx等时,这不会相应地更新apawx等变量。之所以如此是通过导入变量,使您的名称在functions模块中是本地的,因此从函数中重新绑定它们只会影响functions模块命名空间。

如果还不是很清楚,可以将模块的范围视为变量名称是键的位置。如果您有两个答案A和B,例如:

A = {"ap":[], "aw":[]}
B = {}

当你在functions时:

from g import ap, aw

就好像你在做什么

B["ap"] = A["ap"]
B["aw"] = A["aw"]

在此阶段,AB中的键引用相同的对象,因此如果您改变B["ap"](即通过向其添加内容),它将在{{ 1}}:

A

但是,如果您重新绑定 B [“ap”]到新列表,则B["ap"].append(1) print A["ap"] 不会受到影响,A["ap"]B["ap"]将会现在引用两个不同的对象:

A["ap"]

FWIW,模块命名空间就是这样:dicts。

所以简而言之:这不会按预期工作......所以你要么必须将所有变量移动到与使用它们的函数相同的模块中(并在函数中将它们声明为全局变量)使用它们)或与B["ap"] = [42, 43] print A["ap"] 等一起生活

这就是说:全局变量是一个糟糕的主意,无论他们住在哪里。如果你有一组函数正在处理(变异和重新绑定)同一组变量,你通常希望将整个事件变成一个类:

g.ap

答案 1 :(得分:0)

from g import ap, awx, aex, rhs
print(ap, awx, aex, rhs)

如果您不想显式声明变量名称,可以使用from g import *,但通常不建议这样做。原因是明确说明变量名称可以清楚地知道哪些变量来自哪里。如果您说from g import *from h import *然后开始使用它们的一些变量,那么很难说如果没有读取其他文件,哪个来自哪个变量。即使只从一个文件导入,在阅读文件之前(通过阅读文件顶部)知道哪些名称来自其他地方也是很好的。

编辑:如果您想使用此样式但又希望能够修改g中包含的值,则需要这些变量 mutable 对象。您可以使用数组执行此操作。

g.py:

import numpy as np
# variables, dtype is float64 by default
ap = np.array([0.0])
awx = np.array([0.0])
aex = np.array([0.0])
rhs = np.array([0.0])

functions.py:

from g import ap, awx, aex, rhs

def bc_Neumann(i, m, nx):
    m[0] = int(i)
    m[1] = int(i-1)
    m[2] = int(i+1)
    if i == 0:
        m[1] = nx-1
        ap[0] = ap + awx
        awx[0] = 0.0
    if i == nx-1:
        m[2] = 0
        ap[0] = ap + aex
        aex[0] = 0.0
    return m

如果您希望apawx等作为浮动等不可变对象保留,那么您的代码应保持原样,例如使用g.ap

答案 2 :(得分:-1)

使你的变量成为字典的一部分(或者SimpleNameSpace,如果括号打扰你)。

g.py

import numpy as np
# variables
G = dict(ap  = np.float64(0.0),
         awx = np.float64(0.0),
         aex = np.float64(0.0),
         rhs = np.float64(0.0))

然后在functions.py中,您可以将其导入为

from g import G

现在您可以访问/更新变量为G [' ap'],G [' awx']等。

这是有效的,因为字典和列表始终被视为参考。