python - 同一个 Python 模块的两个实例?

标签 python python-2.7 python-module python-internals

我创建了一个 Python 模块,它只有一个函数,它只打印“a!”。我打开了 Python 解释器并以 2 种不同的语法导入了模块

>>> import a
>>> from a import func
>>> func()
a!
>>> a.func()
a!

此时我改变了 func 来打印其他东西,然后再次计算

>>> func()
a!
>>> a.func()
a!

这当然是预料之中的,因为模块没有重新加载。然后我重新加载了模块并期望两个函数都更新,但是:

>>> reload(a)
<module 'a' from 'a.py'>
>>> a.func()
aasd!
>>> func()
a!

似乎只有 a.func 更新了。我一直认为 Python 只保留同一个模块的单个实例,但现在似乎有两个。我做了进一步的测试以验证我的说法,并在模块的顶层添加了一个打印语句,然后重新启动解释器并再次导入:

>>> import a
module imported
>>> import a
>>> from a import func

这让我更加困惑,因为我预计会看到两次“模块导入”。我做的第三个实验是全局变量实验:

>>> import a
module imported
>>> from a import GLOBAL_VAR
>>> GLOBAL_VAR = 5
>>> a.GLOBAL_VAR
1
>>> GLOBAL_VAR
5
>>> GLOBAL_VAR is a.GLOBAL_VAR
False

所以模块只有一个实例,但内部对象有不同的实例?如何实现 Gevent's monkey patching有这样的行为?

最佳答案

模块一旦被导入,就只是另一个 python 对象。所以看到下面的例子,你的结果应该不会让你吃惊:

x = SomeObject()
x.y = 1
a = x.y
x.y = 2
print(a) #a is still 1, not 2

当您执行 from module import name 时,会在当前命名空间中创建一个变量 name,它包含对导入内容的引用(无论是包/模块/类/任何)。它是以下内容的语法糖:

import module
name = module.name

现在,当您重新加载 module 时,您显然不会更新引用 name 的内容。

关于你的第二个实验,一个模块在导入后缓存在 sys.modules 中;后续导入将利用缓存。因此,所有直接在模块级别的代码,如您的 print,只会在第一次导入时执行。

关于python - 同一个 Python 模块的两个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20605799/

相关文章:

python - 使用 7zip 和 python 在给定路径中创建受密码保护的文件

python - 在 Django 中重新保存模型实例不起作用,但 update() 确实起作用

python - 在 Python 3 中使用 Python 2 字典比较

python - 如何在 C++ 中为 Cython 中的两种类型使用模板化函数?

python - 如何调用另一个 lambda 异步并将上下文传递给它?

python - 如何动态共享包范围的配置变量?

python - 在python中多次从外部文件调用变量

Python:模块导入层次结构(启动时不存在的模块)

python - 将包含类别的列与包含整数的列合并

python - 分隔某些列中具有相同值的行