Python导入如何正确工作?

我有两个特定的情况,我不明白如何在Python中导入工程:

第一具体情况:

当我用两个不同的Python脚本导入相同的模块时,模块不会被导入两次,对吧? Python第一次遇到它,它被导入,第二次检查模块是否已经被导入,或者是否复制?

第二具体情况:

考虑下面的模块,称为bla.py

 a = 10 

然后,我们有foo.py ,一个导入bla.py的模块:

 from bla import * def Stuff (): return a 

之后,我们有一个名为bar.py的脚本,由用户执行:

 from foo import * Stuff() #This should return 10 a = 5 Stuff() 

这里我不知道: Stuff()返回10还是5?

第1部分

该模块只加载一次,所以没有再次导入性能损失。 如果你真的想要它被再次加载/parsing,你必须reload()模块。

检查的第一个地方是sys.modules ,以前导入的所有模块的caching。 [ 来源 ]


第2部分

from foo import *import到本地范围。 当赋值给a ,它被replace为新的值 – 但是原始的foo.avariables没有被触及。

所以除非你import foo并修改foo.a ,否则两个调用都会返回相同的值。

对于一个可变types,如列表或字典,它将是不同的,修改它确实会影响原来的variables – 但分配一个新的值将不会修改foo.whatever

如果你想了解一些更详细的信息,请看http://docs.python.org/reference/executionmodel.html

下面的结构绑定名称:函数的forms参数, 导入语句 ,类和函数定义(这些定义块中的类或函数名称绑定在一起),以及作为标识符的目标(如果出现在赋值中)在with语句中的except子句头的位置或之后。

这两个大胆的部分对你来说是相关的:首先,在导入期间,名字a被绑定到foo.a的值。 然后,当a = 5 ,名字a被绑定到5 。 由于修改列表/字典不会导致任何绑定,这些操作会修改原来的( bfoo.b绑定到您操作相同的对象)。 为b指定一个新的对象将是一个绑定操作,因此将bfoo.b分开。

还值得注意的是, import声明究竟做了什么:

  • import foo将模块名称绑定到当前作用域中的模块对象,因此如果修改了foo.whatever ,那么将使用该模块中的名称 – 任何修改/赋值都将影响模块中的variables。
  • from foo import bar绑定给定名称(即foo将保持未绑定)到foo具有相同名称的元素 – 因此, bar操作行为如前所述。
  • from foo import *行为与上一行类似,但是它会导入所有未加下划线的全局名称。 如果模块定义了__all__只有在这个序列中的名字被导入。

第3部分 (甚至不存在你的问题:P)

python文档非常好,通常很冗长 – 你可以在那里find关于几乎所有可能的语言相关问题的答案。 这里有一些有用的链接:

回答你的第一个问题:

不,python不会被“导入”两次。 当python加载模块时,它会检查sys.modules的模块。 如果它不在那里,就放在那里,然后装上。

要回答你的第二个问题:

模块可以定义他们from camelot import *场景中导出的名称,行为是为现有值创build名称,而不是引用现有variables(python没有引用)。

在一个有点相关的话题上, from camelot import * 和做一个常规导入不一样 。