我正在尝试复制一个旧系统。它基于旧的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
方法的现有代码兼容时,请参阅该方法