社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

为什么在windows上python 3下创建模块后导入会失败?

F.X. • 4 年前 • 1033 次点击  

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

# 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)下不工作:

$ 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'

添加 time.sleep(5) 在每个 import printX 打电话就行了。

为什么?

注意:这是 issue 我在想办法。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/40012
 
1033 次点击  
文章 [ 1 ]  |  最新文章 4 年前
Martijn Pieters
Reply   •   1 楼
Martijn Pieters    5 年前

我想我知道发生了什么。新的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文件系统中, 纽约时报 是出了名的低,高达2秒。对于您的情况,分辨率显然仍然很低,缓存无法 在尝试加载第二个模块时更新。虽然ntfs文件系统可以以100ns为增量记录时间,但实际上,限制因素似乎是windows系统时钟,据我所知,它通常被限制为15ms的分辨率。 print2.py 写作后15分钟内 print1.py ,则python不会注意到。

python确实提供了清除这个缓存的方法;使用 importlib.invalidate_caches() method ;这将重置 _path_mtime 属性 FileFinder 实例返回到 -1 ,强制 _填充缓存() 打电话。

正如职能部门的文件所述:

如果在程序运行时创建/安装了任何模块,则应调用此函数,以确保所有查找程序都会注意到新模块的存在。