绝对导入如何与 sitecustomize.py 中的不相关导入一起使用?

我有一个带有不幸命名模块的包:


(dev) go|c:\srv\tmp\absimp> tree myapp

myapp

|-- __init__.py

|-- calendar.py

`-- tst.py

有内容


__init__.py: 空的。


myapp\calendar.py:


from __future__ import print_function

print("imported:", __file__)

myapp\tst.py(第二行打印当前工作目录(cwd)和 cwd 下所有在 python 模块搜索路径上的目录:


from __future__ import print_function, absolute_import

import sys,os; cwd=os.getcwd(); print("CWD:", cwd, "PATH:", [p for p in sys.path if p.startswith(cwd)])


import calendar

print("CALENDAR from myapp/tst:", calendar.__file__)

myapp\tst.py想要导入 Python 的全局calendar模块,所以我启用absolute_import了它,但没有将其导入为from . import calendar.


站在 myapp 目录之外,我仍然得到本地calendar.py(Pythons 2.7.16 和 3.8.0 - 输出相同):


(dev) go|c:\srv\tmp\absimp> python myapp\tst.py

CWD: c:\srv\tmp\absimp PATH: ['c:\\srv\\tmp\\absimp\\myapp']

imported: c:\srv\tmp\absimp\myapp\calendar.py

CALENDAR from myapp/tst: c:\srv\tmp\absimp\myapp\calendar.py

从第一行输出我看到 Python 已将tst.py's 目录添加到sys.path.


如果我编辑我的sitecustomize.py文件,添加


import _strptime

并重新运行上面的命令,我现在得到了全局calendar...:


(dev) go|c:\srv\tmp\absimp> python myapp\tst.py

CWD: c:\srv\tmp\absimp PATH: ['c:\\srv\\tmp\\absimp\\myapp']

CALENDAR from myapp/tst: c:\python27\Lib\calendar.pyc

到底是怎么回事?


蛊毒传说
浏览 97回答 1
1回答

森林海

这是因为_strptime导入calendar本身,甚至在主脚本的路径放在 上之前PATH,因为您指定导入sitecustomize.py(这些导入是预先完成的)。现在calendar已经在模块缓存中,因此不会再次导入,但缓存中的那个将被重用:>>> import sys>>> 'calendar' in sys.modulesFalse>>> import _strptime>>> 'calendar' in sys.modulesTrue事实上,无论存储什么类型的对象,sys.modules它都会以模块名称作为键来匹配。例如:>>> import sys>>> sys.modules['calendar'] = 'foo'>>> import calendar>>> print(calendar)foo
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python