[英]Global variables in Python through modules/file import
問題 :
我試圖找到一種不太笨拙的方式來使用(或完成類似於)全局變量的方法。 現在,我將所有全局變量存儲在文件g.py中 ,因此我使用g.var
訪問它們。
我想在代碼中使用var
而不是g.var
,因為我認為它看起來更干凈。
詳細資料 :
我現在有3個文件:
main.py
:解決PDE的小代碼 functions.py
:定義用於應用邊界條件的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.ap
, g.awx
等? 我只想將這些全局變量引用為ap
, awx
等。
您可以直接導入變量,即:
from g import ap, awx, aex, rhs
然后在函數中將它們聲明為全局變量(否則將它們視為本地變量,並且在重新綁定它們時會收到UnboundLocalError):
def bc_Neumann(i,m,nx):
global ap, awx, aex, rhs
# your code here
但是當您重新綁定ap
, awx
等時,這不會相應地更新g.ap
, g.awx
等變量。其原因是通過導入變量使名稱在functions
模塊中本地化,從而從中重新綁定它們函數中的內容僅影響functions
模塊的名稱空間。
如果還不清楚,則將模塊的作用域視為變量名稱為鍵的命令。 如果您有兩個字典A和B,例如:
A = {"ap":[], "aw":[]}
B = {}
在functions
執行以下操作:
from g import ap, aw
好像你在做
B["ap"] = A["ap"]
B["aw"] = A["aw"]
在此階段, A
和B
鍵指向相同的對象,因此,如果您對B["ap"]
突變(即,通過在其后面添加一些內容),也將在A
看到它:
B["ap"].append(1)
print A["ap"]
但是,如果改為將B [“ ap”] 重新綁定到新列表,則A["ap"]
不會受到影響,並且B["ap"]
和A["ap"]
現在將引用兩個不同的對象:
B["ap"] = [42, 43]
print A["ap"]
FWIW,模塊名稱空間正是這樣:字典。
因此,總而言之:這將無法按預期工作...因此,您要么必須將所有變量與使用它們的函數移到同一模塊(並在使用它們的函數中將它們聲明為全局變量)或與g.ap
等一起g.ap
話雖這么說:無論變量在哪里, 全局變量都是一個可怕的主意 。 如果您有一組處理(變異和重新綁定)同一組變量的函數,那么您通常會希望將整個事情變成一個類:
class Whatever(object):
def __init__(self):
self.ap = np.float64(0.0)
self.awx = np.float64(0.0)
self.aex = np.float64(0.0)
self.rhs = np.float64(0.0)
def bc_neumann(self, i,m,nx):
m[0] = int(i)
m[1] = int(i-1)
m[2] = int(i+1)
if i == 0:
m[1] = nx - 1
self.ap = self.ap + self.awx
self.awx = 0.0
if i == nx-1:
m[2] = 0
self.ap = self.ap + self.aex
self.aex = 0.0
return m
w = Whatever()
w.bc_neumann(1, [], 42)
from g import ap, awx, aex, rhs
print(ap, awx, aex, rhs)
如果您不想顯式聲明變量名,則可以使用from g import *
,但是通常不建議這樣做。 原因是,明確說明變量名稱可以清楚地表明哪些變量來自何處。 如果from g import *
和from h import *
開始說,然后開始使用它們的某些變量,那么在不讀取其他文件的情況下很難分辨出哪個來自哪個。 即使僅從一個文件導入,也最好在讀取文件之前(通過讀取文件頂部)知道其他地方的名字。
編輯:如果要使用此樣式,但又希望能夠修改g
內包含的值,則需要將這些變量設置為可變對象。 您可以使用數組執行此操作。
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
如果您希望ap
, awx
等保持為不可變對象(如float),則您的代碼應保持不變,例如使用g.ap
使變量成為字典的一部分(如果括號引起您注意,則請輸入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']等。
這是可行的,因為字典和列表始終被視為引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.