[英]Python: importing a sub-package module from both the sub-package and the main package
[英]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/b
和a
目录,以及当前目录本身。
如果我将第一个目录重命名为z
则本地导入有效(对于z
和b
以及适当地更改了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
也不是软件包。
这意味着a
在site-packages
不应该包下去,但...
site
中存在一个.pth
文件,该文件会强制将abc
的site-packages
复制为软件包。
在这一点上,我不确定您想做什么来覆盖它。 听起来您想变得很骇客,并从sys.modules
删除现有软件包,然后强行插入您自己的软件包或类似的东西。 当然,您可以这样做,如果您自己无法猜到的话,我可以向您显示代码。 (或者,您可能希望搜索numpy_override
,也可以使用类似的技巧,以用于已预先安装了numpy
或已通过系统重新安装numpy
。)但是,我认为您最好这样做首先重新考虑您的问题。 例如,为什么不构建一个包含您的软件包而不是其site-packages
中的system site-packages
软件包的virtualenv
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.