Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 导入变量初始化_Python_Python 3.x - Fatal编程技术网

Python 导入变量初始化

Python 导入变量初始化,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

我想知道为什么在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

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子句中的名称,否则使用属性名称

  • 这里的关键字是本地名称空间中的

    ,因此您希望从调用代码更改导入模块的状态。为什么?配置-我想读取配置,然后稍后访问它。通过调用代码更改动态配置?只是为了澄清:对对象的更改会传播,但将变量重新组合到另一个对象不会。