我是python的新手,在这里理解范围时遇到一些问题。
我有一个包含三个全局变量的python模块A:
XYZ = "val1"
ABC = {"k1" : "v1", "k2" : "v2"}
PQR = 1
class Cls_A() :
def sm_fn_A(self) :
global XYZ
global ABC
global PQR
XYZ = "val2"
ABC["k1"] = "z1"
ABC["k3"] = "v3"
PQR += 1
另一个模块B:
from A import Cls_A, XYZ, ABC, PQR
class Cls_B():
def sm_fn_B(self) :
Cls_A().sm_fn_A()
print XYZ
print ABC
print PQR
Cls_B().sm_fn_B()
这给了我以下输出:
val1
{'k3': 'v3', 'k2': 'v2', 'k1': 'z1'}
1
由于这些都是全局变量,为什么我没有得到所有打印的全局变量的更新值?
答案 0 :(得分:1)
在模块A
中定义了三个全局变量,在此代码中:
XYZ = "val1"
ABC = {"k1" : "v1", "k2" : "v2"}
PQR = 1
然后新的全局变量XYZ
,ABC
,PQR
在模块B
中定义,在此代码中:
from A import Cls_A, XYZ, ABC, PQR
这行代码创建了新变量,就像写了以下内容一样:
import A
XYZ = A.XYZ
ABC = A.ABC
PQR = A.PQR
重要的是要理解A.XYZ
和B.XYZ
是指向同一对象的两个变量。它们不是同一个变量。
然后将新对象分配给A.XYZ
:
XYZ = "val2"
此修改后的A.XYZ
,但未修改B.XYZ
。这两个变量指向同一个对象,但现在A.XYZ
指向不同的对象。
另一方面,A.ABC
不与不同的对象相关联。相反,对象本身被修改。修改对象后,A.ABC
和B.ABC
仍然指向同一个对象:
ABC["k1"] = "z1"
ABC["k3"] = "v3"
第三种情况也不是对象修改的情况,而是重新分配:
PQR += 1
该值增加。这创建了一个新对象,而不是将新对象分配给A.PQR
。 B.PQR
没有变化。这相当于:
PQR = PQR + 1
可能不太明显的一点是,Python中的字符串和整数都是不可变的对象(无法将数字更改为2
成为3
- 一个人只能为变量分配一个不同的int对象,而不是改变现有的一个。因此,实际上无法以影响A.XYZ
的方式更改B.XYZ
。
字典“工作”的原因是对象被修改了。如果为A.ABC
分配了新的编号,则无效。 E.g。
ABC = {'k3': 'v3', 'k2': 'v2', 'k1': 'z1'}
现在它不会影响B.ABC
,因为A.ABC
中的对象未被更改。另一个对象已分配给A.ABC
。
在没有任何模块的情况下可以看到相同的行为:
A_XYZ = "val1"
A_ABC = {"k1" : "v1", "k2" : "v2"}
A_PQR = 1
B_XYZ = A_XYZ
B_ABC = A_ABC
B_PQR = A_PQR
A_XYZ = "val2"
A_ABC["k1"] = "z1"
A_ABC["k3"] = "v3"
A_PQR += 1
print B_XYZ
print B_ABC
print B_PQR
打印:
val1
{'k3': 'v3', 'k2': 'v2', 'k1': 'z1'}
1
好吧,不要继续引用临时对象。使用具有正确值的变量。
例如,在模块B
中:
import A
class Cls_B():
def sm_fn_B(self) :
A.Cls_A().sm_fn_A()
print A.XYZ
print A.ABC
print A.PQR
Cls_B().sm_fn_B()
现在实际上没有B.XYZ
变量,这可能是错误的。始终使用A.XYZ
。