问题发现
首先是一个使用全局变量的一个文件:
#a.py
import b
g = 10
def func1():
global g
print(g)
g += 1
if __name__ =='__main__' :
func1()
print(g)
b.func2()
不看最后b.func2
,很明显结果是
10
11
此时全局变量g已经变成11了。
#b.py
import a
def func2():
bg = a.g
print(bg)
然而当调用b.func2
时,打印的数字是10,也就是说a的全局变量的改变并没有传递给b。
问题分析
python内置了id函数,每个地址都有独一无二的id,所以看id就可以很明白的知道数字是多少
#===================a.py======================
import b
g = 10
def func1():
global g
print(g)
g += 1
if __name__ =='__main__' :
print("id g:",id(g))
print("id 10:",id(10))
func1()
print(g)
print("id g:",id(g))
print("id g:",id(11))
b.func2()
#==================b.py====================
import a
def func2():
bg = a.g
print("id a.g:",id(a.g))
print("id bg:",id(bg))
print(bg)
运行结果为
id g: 140733566137456
id 10: 140733566137456
10
11
id g: 140733566137488
id g: 140733566137488
id a.g: 140733566137456
id bg: 140733566137456
10
可以发现,当最初g为10时,g和10的id一样,g+1变为11时,id也一样。而当传递到b时,a.g的id就和10的id一样,并且没有随着a中的全局变量的改变而改变。
解决方案
由于本质需求就是想要跨文件共享全局变量,所以比较好的办法是用第三个文件作为全局变量库,用于存储需要共享的全局变量。为了安全起见,可以考虑采用两个函数接口来获取/修改全局变量,而不是直接访问。
#==============a.py================================================
from global_val import global_get,global_set
import b
def func1():
ag = global_get('g')
print('ag:',ag)
ag += 1
global_set('g',ag)
if __name__ =='__main__' :
func1()
print(global_get('g'))
b.func2()
print(global_get('g'))
#==============b.py================================================
from global_val import global_get,global_set
def func2():
bg = global_get('g')
print('bg:',bg)
bg += 1
global_set('g',bg)
#==============global_val.py====================================
g_dict = {
'g':10
}
def global_get(key):
try:
return g_dict[key]
except KeyError:
return False
def global_set(key, value):
try:
g_dict[key] = value
except KeyError:
return False
运行结果为
ag: 10
11
bg: 11
12
Problem solved.