python: 导入的模块在不同的上下文中

python: imported module is in a different context

我正在尝试修改另一个模块中的变量。修饰符方法也在该模块中。显然,上下文发生了变化,修改不会持续存在。

Test1.py

from Test2 import *

function()
print var

Test2.py

var = 0

def function():
    global var
    var = 1

如果我执行Test1.py,即使函数已经执行,结果总是0。

解决此问题的两种方法是:

  1. 调用函数后再次导入东西
  2. 将导入语句替换为 "import Test2" 并将路径添加到对 Test2 的任何调用。

这些解决方案有效,但我想了解为什么会发生这种情况,为什么上下文在导入变量时不混合变量。

从另一个模块导入很像赋值,当 Test2 中的 var 被赋值时,Test1 中的 var 变量未被赋值。

表达式 from Test2 import * 在后台执行此操作:

  • 加载 Test2.py 文件(如果尚未加载),创建 sys.modules['Test2'] 模块对象。如果该对象已经存在,则跳过此步骤。
  • 列出 sys.modules['Test2'] 模块对象的所有 public 属性。 Public 名称是不以 _ 开头的任何名称。如果有__all__属性。
  • 在绑定到这些对象的当前命名空间中添加名称:

    var = sys.modules['Test2'].var
    function = sys.modules['Test2'].function
    

请注意,这些是 新分配,给 sys.modules['Test1'] 或 `sys.modules['main' ]模块。

Test2 中分配给 var 全局然后仅设置 sys.modules['Test2'].var,与

相同
var = 1
var2 = var
var = 2

不会改变 var2.

另一方面,如果您仅将 Test2 模块作为全局模块导入

import Test2

那么您实际上是在要求 Python 使用 Test2 = sys.modules['Test2'],从那以后 Test2.var 引用 相同的变量 =14=] 在 Test2 模块中。这与您这样做的方式相同:

class Test2:
    var = 0

    @classmethod
    def method(cls):
        cls.var = 1

test2 = Test2()
test2.method()
print(test2.var)