Python导入究竟是如何工作的?
我有两种特殊情况,我不明白在Python中导入是如何工作的: 第一种具体情况: 当我在两个不同的Python脚本中导入同一个模块时,该模块不会被导入两次,对吗?Python第一次遇到它时,它被导入,第二次,它是检查模块是否已导入,还是复制 第二种具体情况: 考虑以下名为Python导入究竟是如何工作的?,python,import,module,Python,Import,Module,我有两种特殊情况,我不明白在Python中导入是如何工作的: 第一种具体情况: 当我在两个不同的Python脚本中导入同一个模块时,该模块不会被导入两次,对吗?Python第一次遇到它时,它被导入,第二次,它是检查模块是否已导入,还是复制 第二种具体情况: 考虑以下名为bla.py的模块: a = 10 from bla import * def Stuff (): return a 然后,我们有foo.py,一个导入bla.py的模块: a = 10 from bla impo
bla.py
的模块:
a = 10
from bla import *
def Stuff ():
return a
然后,我们有foo.py
,一个导入bla.py
的模块:
a = 10
from bla import *
def Stuff ():
return a
然后,我们有一个名为bar.py
的脚本,由用户执行:
from foo import *
Stuff() #This should return 10
a = 5
Stuff()
这里我不知道:
Stuff()
返回10还是5?第1部分
模块只加载一次,因此再次导入不会导致性能损失。如果您确实希望再次加载/解析它,则必须reload()
模块
选中的第一个位置是sys.modules
,它是以前导入的所有模块的缓存。[]
第二部分
从foo导入*
将a
导入到本地范围。将值赋给a
时,会用新值替换该值-但不会触及原始foo.a
变量
因此,除非您导入foo
并修改foo.a
,否则两个调用将返回相同的值
对于一个可变类型,如列表或dict,它会有所不同,修改它确实会影响原始变量-但是给它分配一个新值仍然不会修改foo.whatever
如果您想了解更多详细信息,请查看:
以下构造绑定名称:函数的形式参数、导入语句、类和函数定义(它们绑定定义块中的类或函数名称),以及目标(如果发生在循环头的赋值中,则为标识符),位于except子句头的第二个位置或后面,如with语句中
两个粗体部分与您相关:首先,名称a
在导入期间绑定到foo.a
的值。然后,在执行a=5
时,名称a
绑定到5
。由于修改列表/目录不会导致任何绑定,因此这些操作将修改原始列表/目录(b
和foo.b
绑定到您操作的同一对象)。将新对象分配给b
将再次成为绑定操作,从而将b
与foo.b
分开
还值得注意的是,import
语句的确切功能:
将模块名称绑定到当前作用域中的模块对象,因此如果修改import foo
,您都将使用该模块中的名称-任何修改/分配都将影响模块中的变量foo。无论什么
仅将给定名称(即from foo import bar
将保持未绑定状态)绑定到foo
中具有相同名称的元素-因此foo
上的操作与前面解释的操作类似bar
的行为与前一个类似,但它导入所有不带下划线前缀的全局名称。如果模块定义了from foo import*
,则只导入此序列中的名称\uuuuuuuuuuuuuuuuuuuu
第三部分(你的问题中根本不存在:p) python文档非常好,而且通常很冗长——您可以在这里找到几乎所有可能与语言相关的问题的答案。以下是一些有用的链接:
- (类、属性、魔术方法等)()
- (python中变量的工作方式)
- (如
,import
等语句)yield
- (块语句,例如
,for
,try
)with
的名称,其行为是为现有值创建名称,而不是引用现有变量(python没有引用)
关于一个有点相关的主题,从camelot import*
执行是。运行代码时发生了什么?您可能会发现以下有趣的内容:和。它们都在Python中处理导入。因为“from foo import*”将模块foo中的所有内容都带到了bar的本地名称空间中,所以我们在bar的本地名称空间中既有函数Stuff,也有变量“a”[就好像它们是在bar模块中创建的一样],那么,为什么将a设置为5并在bar模块中调用stuff不返回5呢?看来ThiefMaster在回答编辑问题上击败了我。我把这个放在这里只是为了保持“from camelot import*
与常规导入不一样。”因为“from foo import*”将模块foo中的所有内容都带到了bar的本地名称空间中,所以我们在bar的本地名称空间中有函数Stuff和变量“a”[就好像它们是在bar模块中创建的一样],那么为什么将a设置为5并在bar模块中调用stuff不会返回5呢?因为“from foo import*”将模块foo中的所有内容都带到了bar的本地名称空间中,所以我们在bar的本地名称空间中有函数stuff和变量“a”[就好像它们是在bar模块中创建的一样],那么为什么将a设置为5并在bar模块中调用stuff不会返回5呢?