繁体   English   中英

与站点包冲突时,从当前目录中的子包导入模块

[英]Importing module from sub-package in current directory when it clashes with site-packages

我的site-packages目录中的abcd软件包中有模块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]是空字符串。 我期望并因此在documentation / Google中找到当前目录的优先级。 我也尝试添加__init__.py在当前目录下的a/ba目录,以及当前目录本身。

如果我将第一个目录重命名为z则本地导入有效(对于zb以及适当地更改了import语句,都使用了额外的__init__.py s)。

site-packages包含abc-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已经包含该模块了吗? 我可以强迫它以某种方式被覆盖吗?

根据您的评论,问题是:

  • 您的a不是包,因为在Python 3.3之前,没有__init__.py文件的目录永远不是包。 这意味着您的abc也不是软件包。

  • 这意味着asite-packages不应该包下去,但...

  • site中存在一个.pth文件,该文件会强制将abcsite-packages复制为软件包。

在这一点上,我不确定您想做什么来覆盖它。 听起来您想变得很骇客,并从sys.modules删除现有软件包,然后强行插入您自己的软件包或类似的东西。 当然,您可以这样做,如果您自己无法猜到的话,我可以向您显示代码。 (或者,您可能希望搜索numpy_override ,也可以使用类似的技巧,以用于已预先安装了numpy或已通过系统重新安装numpy 。)但是,我认为您最好这样做首先重新考虑您的问题。 例如,为什么不构建一个包含您的软件包而不是其site-packages中的system site-packages软件包的virtualenv

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM