python - Python 导入究竟是如何工作的?

标签 python import module

我有两种具体情况我不明白 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 部分

该模块仅加载一次,因此再次导入不会造成性能损失。如果您真的希望再次加载/解析它,您必须 reload()模块。

The first place checked is sys.modules, the cache of all modules that have been imported previously. [source]


第 2 部分

from foo import *进口 a到本地范围。给 a 赋值时, 它被新值替换 - 但原来的 foo.a变量没有被触及。

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

对于可变类型,例如列表或字典,它会有所不同,修改它确实会影响原始变量 - 但为其分配新值仍然不会修改foo.whatever .

如果您想了解更多详细信息,请查看 http://docs.python.org/reference/executionmodel.html :

The following constructs bind names: formal parameters to functions, import statements, class and function definitions (these bind the class or function name in the defining block), and targets that are identifiers if occurring in an assignment, for loop header, in the second position of an except clause header or after as in a with statement.

两个粗体部分与您相关:首先是名称 a绑定(bind)到 foo.a 的值在导入期间。然后,在做 a = 5 时, 名称 a绑定(bind)到5 .由于修改列表/字典不会导致任何绑定(bind),因此这些操作将修改原始的(bfoo.b 绑定(bind)到您操作的同一对象)。将新对象分配给 b将再次成为绑定(bind)操作,因此将 b 分开来自 foo.b .

还值得注意的是 import 到底是什么声明:

  • import foo将模块名绑定(bind)到当前作用域的模块对象,所以如果修改foo.whatever ,您将使用该模块中的名称 - 任何修改/分配都会影响模块中的变量。
  • from foo import bar仅将给定名称(即 foo 将保持未绑定(bind))绑定(bind)到 foo 中具有相同名称的元素- 所以对 bar 的操作行为如前所述。
  • from foo import *行为与前一个类似,但它导入所有不带下划线前缀的全局名称。如果模块定义了 __all__仅导入此序列中的名称。

第 3 部分(您的问题中甚至不存在:p)

python 文档非常好,而且通常很冗长——您可以在其中找到几乎所有可能与语言相关的问题的答案。以下是一些有用的链接:

关于python - Python 导入究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10501724/

相关文章:

python - 数据驱动框架 : Web/Desktop Camelot V Django etc

python - 如果 Flask catch-all 路由以前缀开头,则引发 404

mysql - 导入 MySQL 转储文件时如何覆盖 ENGINE=INNODB 参数?

reactjs - 如何使用变量在 React 中导入组件或文件?

module - 两个模块,都导出相同的名称

python - 在具有导入函数的模块上使用 pydoc

git - 发布和维护 Nodejs 模块

python - 多次try-except不带exec()的解决办法

python - 长轮询的Ajax无法在网页上显示celery结果

xcode - 使用 Cocoapods 导入 SwiftyJSON 时出错