[英]Importing module from sub-package in current directory when it clashes with site-packages
I have module e
in package abcd
in my site-packages
directory: 我的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
is empty in both cases. 两种情况下__init__.py
均为空。 I mirror this directory structure in my current directory: 我将此目录结构镜像到当前目录中:
a/b/c/__init__.py
a/b/c/d/__init__.py
a/b/c/d/e.py
I run python 2.7 and type: 我运行python 2.7并输入:
from a.b.c.d.e import foo
The site-packages
version is imported instead of the local version. site-packages
版本将被导入,而不是本地版本。 sys.path[0]
is the empty string. sys.path[0]
是空字符串。 I expect and find in documentation/Google that the current directory takes precedence because of this. 我期望并因此在documentation / Google中找到当前目录的优先级。 I've also tried adding __init__.py
in the current directory's a/b
and a
directories, as well as the current directory itself. 我也尝试添加__init__.py
在当前目录下的a/b
和a
目录,以及当前目录本身。
If I rename the first directory to z
then the local import works (with the extra __init__.py
s in place for z
and b
and import statement appropriately changed). 如果我将第一个目录重命名为z
则本地导入有效(对于z
和b
以及适当地更改了import语句,都使用了额外的__init__.py
s)。
site-packages
contains abc-VERSION-nspkg.pth
: 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)
Why can I not override the module like this? 为什么不能这样覆盖模块? Is it perhaps because sys.modules
already contains the module? 可能是因为sys.modules
已经包含该模块了吗? Can I force it to be overridden somehow? 我可以强迫它以某种方式被覆盖吗?
From your comments, the problem is: 根据您的评论,问题是:
Your a
is not a package, because before Python 3.3, a directory without an __init__.py
file is never a package. 您的a
不是包,因为在Python 3.3之前,没有__init__.py
文件的目录永远不是包。 This means your abc
isn't a package either. 这意味着您的abc
也不是软件包。
This means the a
in site-packages
shouldn't a package either, but… 这意味着a
在site-packages
不应该包下去,但...
There's a .pth
file in site
that forces the site-packages
copy of abc
to be a package anyway. site
中存在一个.pth
文件,该文件会强制将abc
的site-packages
复制为软件包。
At this point, I'm not sure what you want to do to override this. 在这一点上,我不确定您想做什么来覆盖它。 It sounds like you want to get really hacky and delete the existing package from sys.modules
and then forcibly insert your own, or something like that. 听起来您想变得很骇客,并从sys.modules
删除现有软件包,然后强行插入您自己的软件包或类似的东西。 Of course you can do that, and I can show you the code if you can't guess it yourself. 当然,您可以这样做,如果您自己无法猜到的话,我可以向您显示代码。 (Or you may want to search for numpy_override
, which does a similar trick, for use on systems that come with an out-of-date pre-installed or system-repo-installed numpy
.) But I think you'd be better off rethinking your problem in the first place. (或者,您可能希望搜索numpy_override
,也可以使用类似的技巧,以用于已预先安装了numpy
或已通过系统重新安装numpy
。)但是,我认为您最好这样做首先重新考虑您的问题。 For example, why not just build a virtualenv
that has your package instead of the system site-packages
package in its site-packages
? 例如,为什么不构建一个包含您的软件包而不是其site-packages
中的system site-packages
软件包的virtualenv
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.