当同一模块多次导入同一环境时,模块和作用域如何交互?

enk*_*iv2 5 python scope module

假设我们有模块ABC,并且该模块在模块范围内C有一些变量。X

A导入B,(出于其自身目的)导入CA也直接进口C

如果A改变 的值,那么看到C.X的值会改变吗?同样,如果改变 的值,会改变看到的值吗?C.XBBC.XA

换句话说,当一个模块多次导入到同一个解释器上下文中时,该模块名称空间中的可变变量是否有效地共享内存?

jfa*_*oni 7

如果A改变 的值,那么看到C.X的值会改变吗?C.XB

长话短说:博士

这取决于您如何导入 X以及其X变性

import C

如果两者A都使用语句B导入C模块import C,则它们都可以访问和修改C.X. 该名称X绑定到C模块,并且A和 都B可以访问该模块。例子:

py

X = 1
Run Code Online (Sandbox Code Playgroud)

py

import C

def func():
     print(C.X)
Run Code Online (Sandbox Code Playgroud)

py

import B
import C

C.X = 2
B.func()
Run Code Online (Sandbox Code Playgroud)

运行A.pyprints 2-A有效地修改了模块名称空间X的属性,并且此更改在调用时C反映。Bfunc()

from C import X

from _ import _语句从外部模块获取一个属性并将其绑定到当前模块。当模块从A导入时,它只是将该值绑定到的命名空间。换句话说,对in命名空间的更改不会反映对or的更改。例子:XCAXAB.XC.X

py

X = 1
Run Code Online (Sandbox Code Playgroud)

py

from C import X

def func():
     print(X)
Run Code Online (Sandbox Code Playgroud)

py

import B
from C import X

X = 2
B.func()
Run Code Online (Sandbox Code Playgroud)

运行A.pyprints 1,因为B.func()将打印存储在 的值B.X,而我们只修改了A.X

如果X是可变的怎么办?

如果X是可变的(列表、字典、用户定义的类或实例等),那么如何导入它并不重要 - 改变任何模块中导入的对象将在所有模块中传播。例子:

py

X = {}  # mutable object (empty dictionary)
Run Code Online (Sandbox Code Playgroud)

py

from C import X

def func():
     print(X)
Run Code Online (Sandbox Code Playgroud)

py

import B
import C

C.X['key'] = 'value'
B.func()
Run Code Online (Sandbox Code Playgroud)

运行A.py打印{'key': 'value'}。我们有效地修改了同一个对象,尽管A使用了一个import _语句,并且B使用了一个from _ import _语句。对于任何可变对象都是如此,无论如何AB导入它。