包上的`del`有某种记忆

时间:2018-02-15 14:20:59

标签: python python-3.x ipython packages del

del似乎有一些困扰我的记忆。请参阅以下内容:

In [1]: import math

In [2]: math.cos(0)
Out[2]: 1.0

In [3]: del math.cos

In [4]: math.cos(0)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-4-9cdcc157d079> in <module>()
----> 1 math.cos(0)

AttributeError: module 'math' has no attribute 'cos'

精细。让我们看看如果我们删除整个数学包会发生什么:

In [5]: del math

In [6]: math.cos(0)
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
<ipython-input-6-9cdcc157d079> in <module>()
----> 1 math.cos(0)

NameError: name 'math' is not defined

所以现在数学本身就像预期的那样消失了。

现在让我们再次导入数学:

In [7]: import math

In [8]: math.cos(0)
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-9cdcc157d079> in <module>()
----> 1 math.cos(0)

AttributeError: module 'math' has no attribute 'cos'

所以交互式python以某种方式记得即使在我们删除了整个数学包并再次导入它之后,math.cos也被删除了。

python在哪里保留这些知识?我们可以访问吗?我们可以改变吗?

3 个答案:

答案 0 :(得分:62)

包只从磁盘读取一次,然后作为可变单例存储在内存中。第二次导入它时,您将获得与先前导入的完全相同的单例,并且它仍然缺少其cosdel math只是删除了它的本地名称,它没有&#34; #emp;&#34;整体来自Python的包。

答案 1 :(得分:24)

我会说这个包仍然被视为已导入。因此,再次执行import math只需重新声明名称,但使用旧内容。

你可以使用reload来确保你的模块再次完整,除了某些版本的python还要删除sys.modules中的条目,这样就可以使用reload冗余:

import math
del math.cos
del math
sys.modules.pop("math")   # remove from loaded modules
import math
print(math.cos(0))  # 1.0

(各种python版本reloadimport之间的差异将在后续问题中讨论:Should importlib.reload restore a deleted attribute in Python 3.6?

答案 2 :(得分:15)

del math根本不删除软件包,它只删除当前模块中的本地名称 math

与任何其他对象一样,如果对数学模块的任何其他引用存在于任何地方,那么它将保留在内存中。

特别是,sys.modules始终是所有已加载模块的字典,所以至少在那里总是有一个引用。

编辑:但是有一种方法可以实际重新加载模块imp.reload

不幸的是我无法让它在这种情况下工作,重载需要随机模块(可能是创建编译的Python文件的某些部分),随机模块需要math.cos,它已经消失了。即使首先导入random也没有错误,但math.cos不再出现;我不知道为什么,也许是因为它是一个内置模块。