简体   繁体   中英

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:

/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. 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:

from a.b.c.d.e import foo

The site-packages version is imported instead of the local version. sys.path[0] is the empty string. I expect and find in documentation/Google that the current directory takes precedence because of this. I've also tried adding __init__.py in the current directory's a/b and a directories, as well as the current directory itself.

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).

site-packages contains 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? 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. This means your abc isn't a package either.

  • This means the a in site-packages shouldn't a package either, but…

  • There's a .pth file in site that forces the site-packages copy of abc to be a package anyway.

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. 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. For example, why not just build a virtualenv that has your package instead of the system site-packages package in its site-packages ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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