【发布时间】:2015-07-11 04:37:28
【问题描述】:
我的site-packages 目录中有a.b.c.d 包中的模块e:
/usr/lib/python2.7/site-packages/a/b/c/__init__.py
/usr/lib/python2.7/site-packages/a/b/c/d/__init__.py
/usr/lib/python2.7/site-packages/a/b/c/d/e.py
__init__.py 在这两种情况下都是空的。我在当前目录中镜像了这个目录结构:
a/b/c/__init__.py
a/b/c/d/__init__.py
a/b/c/d/e.py
我运行 python 2.7 并输入:
from a.b.c.d.e import foo
导入的是site-packages 版本,而不是本地版本。 sys.path[0] 是空字符串。我希望并在文档/Google 中发现当前目录因此优先。我还尝试在当前目录的a/b 和a 目录以及当前目录本身中添加__init__.py。
如果我将第一个目录重命名为 z,则本地导入有效(为 z 和 b 设置了额外的 __init__.pys,并适当更改了导入语句)。
site-packages 包含a.b.c-VERSION-nspkg.pth:
import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('a',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('a',types.ModuleType('a')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('a', 'b')); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('a.b',types.ModuleType('a.b')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p); m and setattr(sys.modules['a'], 'b', m)
为什么我不能像这样覆盖模块?可能是因为sys.modules 已经包含该模块?我可以强制以某种方式覆盖它吗?
【问题讨论】:
-
这是什么 Python 版本?在 2.x 和早期 3.x 中,
a不是一个包,如果它没有__init__.py,你的都没有(但站点包可能明确添加了一个 .pth 文件)。在后来的 3.x 中,a是一个命名空间包,会将两者合并在一起(但a.b.c不是,所以必须取其一)。 -
我已经添加了更多的 2.7 参考和详细信息,我尝试添加更多
__init__.pys。 -
来自问题末尾的评论,“可能是因为 sys.modules 已经包含该模块吗?”:如果您已经在当前会话中导入了它,然后尝试更改内容(无论是在文件系统上还是在 sys.path 中),那么是的,那将失败。但是在新的解释器会话中,这些东西没有理由出现在 sys.modules 中。
-
当我启动解释器时,
sys.modules不是空的 - 我相信它包含来自site-packages的所有内容。这同样适用于不同的操作系统/Python 次要版本。 -
它不应该是empty,但如果它实际上包含来自
site-packages的所有内容,那就大错特错了。
标签: python python-2.7 python-import python-module