一直是SO的长期浏览器,终于问了我自己的问题!
所以,我正在编写一个自动化脚本/模块,它递归地在目录中查找具有特定名称的 python 模块。如果我找到一个具有该名称的模块,我会动态加载它,从中提取我需要的内容,然后卸载它。我注意到虽然简单地删除模块并不会删除对该模块的所有引用,但在某个地方还有另一个挥之不去的地方,我不知道它在哪里。我尝试查看源代码,但无法很好地理解它。这是我所看到的示例,大大简化了:
我正在使用 Python 3.5.2(Anaconda v4.2.0)。我正在使用 importlib,这就是我想要坚持的。我也希望能够使用 vanilla python-3 来做到这一点。
我从这里的 python 文档中获得了源代码的导入(是的,我知道这是 Python 3.6 文档)。
我的主要司机...
# main.py
import importlib.util
import sys
def foo():
spec = importlib.util.spec_from_file_location('a', 'a.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
print(sys.getrefcount(module))
del module
del spec
if __name__ == '__main__':
foo()
print('THE END')
我的示例模块...
# a.py
print('hello from a')
class A():
def __del__(self):
print('SO LONG A!')
inst = A()
输出:
python main.py
HELLO FROM A!
2
THE END
SO LONG A!
我期待看到“SO LONG A!” 在“THE END”之前打印。那么,对我的模块的其他隐藏引用在哪里?我知道我的 del 是无偿的,因为我将它包装在一个函数中。我只是希望删除和范围明确。如何让 a.py 完全卸载?我计划动态加载大量像 a.py 这样的模块,并且我不想再坚持使用它们了。有什么我想念的吗?