无法访问导入变量的修改值



我是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

既然这些都是全局变量,为什么我不打印所有全局变量的更新值?

说明

模块A中定义了三个全局变量,在此代码中:

XYZ = "val1"
ABC = {"k1" : "v1", "k2" : "v2"}
PQR = 1

然后在模块B中定义新的全局变量XYZABCPQR,在该代码中:

from A import Cls_A, XYZ, ABC, PQR

这行代码创建了新的变量,就像写了以下内容一样:

import A
XYZ = A.XYZ
ABC = A.ABC
PQR = A.PQR

重要的是要理解A.XYZB.XYZ是指向同一对象的两个变量。它们不是同一个变量。

然后将一个新对象分配给A.XYZ:

    XYZ = "val2"

这修改了A.XYZ,但没有修改B.XYZ。这两个曾经是指向同一对象的两个变量,但现在A.XYZ指向不同的对象。

另一方面,A.ABC不与不同的对象相关联。相反,对象本身会被修改。修改对象时,A.ABCB.ABC仍然指向同一对象:

    ABC["k1"] = "z1"
    ABC["k3"] = "v3"

第三种情况也不是对象修改的情况,而是重新分配:

    PQR += 1

该值已递增。这创建了一个新对象,然后将该新对象分配给A.PQR。CCD_ 16不变。这相当于:

    PQR = PQR + 1

一件可能并不明显的事情是,字符串和整数在Python中都是不可变的对象(无法将数字更改为2以变为3——只能为变量分配一个不同的int对象,而不能更改现有对象(。因此,实际上没有办法以影响B.XYZ的方式更改A.XYZ

字典也可以这样

使用字典"工作"的原因是对象被修改了。如果一个新的dictionary被分配给A.ABC,那将不起作用。例如

    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变量,这可能是错误的。始终使用CCD_ 27。

相关内容

  • 没有找到相关文章

最新更新