我在 /tmp
, insert
其道 sys.path
,导入虚拟模块。del
不需要了,就把它删掉 sys.path
而我仍然能够导入。为什么要这样做?
考虑这个pytest夹具代码及其注释。
def test_function(temp_dir):
with open(os.path.join(temp_dir, 'dum.py'), 'w') as f:
f.write("""
class A:
\"\"\"
test docstring
\"\"\"
test: int
test_2: str = "asdf"
class B(A):
pass
""")
import sys
sys.path.insert(1, temp_dir)
assert temp_dir in sys.path # assertion passes
# noinspection PyUnresolvedReferences
import dum # import successful
yield dum
# teardown executed after each usage of the fixture
del dum # deletion successful
sys.path.remove(temp_dir) # removing from path successful
assert temp_dir not in sys.path # assertion passes
with pytest.raises(ModuleNotFoundError): # fails - importing dum is successful
import dum
为什么要删除它呢?甚至当我通过执行 sys.path = []
. 没有 dum.py
项目目录下的任何地方。我是不是遗漏了什么?Python是否在删除了导入的模块后还在缓存它们?
导入一个模块一次后,下次要导入它时,Python 会首先检查已经导入的模块集合,并使用已经加载的模块。因此,第二次导入模块时。sys.path
甚至没有被查询。
这一点是非常必要的,如果你想一想:假设你直接导入一些模块,每个模块都使用了,其他一些模块,以此类推。如果一个模块必须从磁盘中检索和解析,每次一个 import
语句,你将花费大量的时间来等待模块加载。
同样值得注意的是,当一个模块A第二次导入一个模块B时,实际上什么都不会发生。有一些方法可以显式地重新加载一个已经加载的模块,但通常情况下,你不希望这样做(实时更新的web服务器是一个明显的例外)。
伟大而详细的信息是由 Amitai Irron 在 他的回答,所以去那里了解 何以. 回答以下问题: 如何真正去除它 而无法再次导入),你不仅需要对原问题执行全部删除,还需要。
del sys.modules['dum']
这样就可以把这个模块从 sys.modules
其中保留了所有的缓存模块。感谢 0x5453 为我指出 sys.modules
.