Python 导入变量初始化
我想知道为什么在python(Python3.4)中导入一个变量的结果与导入一个模块然后引用不同,更重要的是为什么要创建一个深度拷贝——有没有办法绕过这个拷贝(而不是定义一个简单返回它的函数) a.pyPython 导入变量初始化,python,python-3.x,Python,Python 3.x,我想知道为什么在python(Python3.4)中导入一个变量的结果与导入一个模块然后引用不同,更重要的是为什么要创建一个深度拷贝——有没有办法绕过这个拷贝(而不是定义一个简单返回它的函数) a.py v = 1 def set(): global v v = 3 from a import v def foo(): print(v) print(a.v) print(id(v)) print(id(a.v)) main.py imp
v = 1
def set():
global v
v = 3
from a import v
def foo():
print(v)
print(a.v)
print(id(v))
print(id(a.v))
main.py
import a
import b
a.set()
b.foo()
b.py
v = 1
def set():
global v
v = 3
from a import v
def foo():
print(v)
print(a.v)
print(id(v))
print(id(a.v))
输出
1
3.
1585041872
1585041904
问题在于您正在修改标量值。这不是一个特定于模块的问题,当简单地将变量传递到函数中并在那里修改它时,它的工作原理是相同的
值1
从a
,句点导入。在a
中执行的任何操作都不会修改该值,因为它是一个简单的不可变标量值
如果a.v
a.v
是一个对象,对该对象的更改将传播到任何包含对它的引用的变量。让我们检查事件序列:
a.v = 1 # a.py: v = 1
b.v = a.v # b.py: from a import v
a.v = 3 # a.set()
print(b.v) # foo(): print(v)
print(a.v) # foo(): print(a.v)
如您所见,
从导入v
实际上将b.v
绑定到a
中的值,随后对原始变量的修改不会影响副本。当您说导入a
时,您正在创建对模块的引用。a、 v没有被复制。我注意到所有模块中都有一个模块的变化。当您从导入v中说时,您是在导入时制作v的副本。如果任何一个变量都改变了,它就不会反映在其他地方。我自己问a,在其他人的帮助下,我弄明白了它是什么。这是我发现的。使用pydoc
链接:
从导入v
中的不会添加对a.v
的引用。相反,当发生import
时,它会向b
添加一个新变量作为b.v
,其值为a.v
。以后更改a.v
不会更改b.v
的值
from表单不绑定模块名:它遍历标识符列表,在步骤(1)中找到的模块中查找每个标识符,并将本地名称空间中的名称绑定到这样找到的对象
from表单使用稍微复杂一些的过程:
查找from
子句中指定的模块,必要时加载并初始化该模块李>
对于导入
条款中指定的每个标识符:
检查导入的模块是否具有该名称的属性
如果没有,请尝试导入具有该名称的子模块,然后再次检查导入的模块是否具有该属性
如果未找到该属性,将引发ImportError
否则,对该值的引用将存储在本地名称空间中,如果存在,则使用as子句中的名称,否则使用属性名称
这里的关键字是本地名称空间中的,因此您希望从调用代码更改导入模块的状态。为什么?配置-我想读取配置,然后稍后访问它。通过调用代码更改动态配置?只是为了澄清:对对象的更改会传播,但将变量重新组合到另一个对象不会。