python如何从不同的位置导入不同的子包



我正在尝试复制一个旧系统。它基于旧的Debian Wheezy(7.1(系统,在守护进程模式下使用Apache 2.2.22和libapache2 mod wsgi 3.3,以及Python 2.7.3。WSGI应用程序使用虚拟机中的包,该虚拟机是通过访问全局站点包模块创建的。它使用来自同一命名空间包的两个子包,由系统安装在不同的位置:

  • repoze.who,安装在/usr/lib/pymodules/python2.7/
  • repoze.lru,安装在/usr/lib/python2.7/dist-packages/

我的问题是它在复制的系统上不起作用:应用程序无法导入repoze.who。另一方面,在原始系统上,它工作在文件中,并成功地导入了这两个子包。

我知道它不应该工作,因为在正常配置中,Python不希望一个包被拆分到几个地方。

我阅读了python导入具有相同根包名称和不同位置的不同子包的问题及其答案。如果我按照建议修改两个repoze/__init__.py文件,它在复制的系统上运行良好。

但我检查了原始系统上的两个文件,它们都是空的。

我在WSGI应用程序中添加了一些print指令,以研究原始系统。sys.path在两个系统上看起来都很好并且相似,两个系统的/usr/lib/python2.7/dist-packages都在/usr/lib/pymodules/python2.7之前。令人惊讶的是,repoze包是从原始系统上的/usr/lib/pymodules/python2.7导入的,而它是从复制系统上的/usr/lib/python2.7/dist-packages导入的。此外,repoze.__path__在原始系统上同时包含这两个位置,而在复制系统上仅包含/usr/lib/python2.7/dist-packages/repoze

最后但同样重要的是,如果我在原始系统上运行virtualenv的python解释器,它在导入repoze.lru文件时无法导入repoze.who包,这看起来是正常的行为。因此,mod wsgi或应用程序一定有一些特别之处。

我想是做了一些"聪明"的事情,允许WSGI应用程序从不同的位置加载两个包,但我不知道是什么。欢迎提出任何建议。

repoze正在使用命名空间包。

从其setup.py:

namespace_packages=['repoze', 'repoze.who', 'repoze.who.plugins'],
  • 有关构建命名空间包的现代方法,请参阅PEP420
  • 请参阅pkg_resources中的旧方法(我个人在2000年代中期就有过这种方法(
  • 当您需要与已经使用pkgutil方法的现有代码兼容时,请参阅该方法

最新更新