为什么在Windows上python3下创建模块后导入失败?

2024-09-29 05:32:16 发布

您现在位置:Python中文网/ 问答频道 /正文

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

# 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上,这两种导入都在Python2(2.7)下工作,但在Python3(3.5和3.6)下不工作:

^{pr2}$

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

为什么?在

注意:这是一个更简单的版本。


Tags: tonamepyimporttimeosmodulepyc
1条回答
网友
1楼 · 发布于 2024-09-29 05:32:16

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

请参见^{} 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系统时钟,据我所知,它的分辨率通常限制在15毫秒以内。因此,如果在写入print1.py的15毫秒内写入print2.py,那么Python不会注意到。在

Python提供了清除缓存的方法;使用^{} 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.

相关问题 更多 >