gpt4 book ai didi

python - 为什么在 Windows 上的 Python 3 下创建模块后导入失败?

转载 作者:可可西里 更新时间:2023-11-01 11:43:31 25 4
gpt4 key购买 nike

以下代码尝试创建然后导入两个模块:

# coding: utf-8

import os
import time

# Remove the modules we're about to create if they already exist
def force_unlink(name):
try:
os.unlink(name)
except OSError:
pass
force_unlink("print1.py")
force_unlink("print1.pyc")
force_unlink("print2.py")
force_unlink("print2.pyc")
time.sleep(1)

# Create module 1 and module 2, then try to import them just afterwards
print("Creating module 1...")
with open("print1.py", "wb+") as fd:
fd.write(b'print("Imported module 1")')
import print1
print("Creating module 2...")
with open("print2.py", "wb+") as fd:
fd.write(b'print("Imported module 2")')
import print2

在 Windows 上,两种导入都可以在 Python 2 (2.7) 下工作,但不能在 Python 3(3.5 和 3.6)下工作:

$ python2 reproduce.py
Creating module 1...
Imported module 1
Creating module 2...
Imported module 2
$ python3 reproduce.py
Creating module 1...
Imported module 1
Creating module 2...
Traceback (most recent call last):
File "reproduce.py", line 26, in <module>
import print2
ImportError: No module named 'print2'

在每个 import printX 调用之前添加 time.sleep(5) 使其工作。

这是为什么?

注意:这是一个简单版本的 issue我在想办法。

最佳答案

我想我知道发生了什么。新的 Python 3 导入机制缓存它在目录中找到的文件名。当目录的修改时间mtime发生变化时,它会重新加载缓存。

参见 importlib._bootstrap_external.FileFinder.find_spec() method implementation ,其中包含:

try:
mtime = _path_stat(self.path or _os.getcwd()).st_mtime
except OSError:
mtime = -1
if mtime != self._path_mtime:
self._fill_cache()
self._path_mtime = mtime

此处 _path_stat 只是一个 os.stat() 调用,但已本地化以避免导入。 _fill_cache() 方法执行 os.listdir() 调用。

在某些 Windows 文件系统上,mtime 的分辨率非常低,最多 2 秒。对于您的情况,分辨率显然仍然足够低,以至于在您尝试加载第二个模块时不会更新缓存。尽管 NTFS 文件系统可以以 100ns 的增量记录时间,但实际上限制因素似乎是 Windows 系统时钟,据我所知通常限于 15ms 的分辨率。因此,如果您在编写 print1.py 后的 15 毫秒内编写 print2.py,则 Python 不会注意到。

Python 确实为您提供了清除此缓存的方法;使用 importlib.invalidate_caches() method ;这会将 FileFinder 实例上的 _path_mtime 属性重置回 -1,强制执行新的 _fill_cache() 调用.

正如该函数的文档所述:

This function should be called if any modules are created/installed while your program is running to guarantee all finders will notice the new module’s existence.

关于python - 为什么在 Windows 上的 Python 3 下创建模块后导入失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52933869/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com