[英]How can python import different subpackages from different locations?
I have an old system that I'm trying to replicate.我有一个我正在尝试复制的旧系统。 It is based on an old Debian Wheezy (7.1) system and uses Apache 2.2.22 and libapache2-mod-wsgi 3.3, in daemon mode, and Python 2.7.3.它基于旧的 Debian Wheezy (7.1) 系统,并在守护进程模式下使用 Apache 2.2.22 和 libapache2-mod-wsgi 3.3,以及 Python 2.7.3。 The WSGI application uses packages from a virtualenv, created with access to the global site-packages modules. WSGI 应用程序使用来自 virtualenv 的包,创建时可以访问全局站点包模块。 It uses two subpackages from the same namespace package, that are installed by the system in different places:它使用来自同一命名空间 package 的两个子包,它们由系统安装在不同的地方:
repoze.who
, installed in /usr/lib/pymodules/python2.7/
repoze.who
,安装在/usr/lib/pymodules/python2.7/
repoze.lru
, installed in /usr/lib/python2.7/dist-packages/
repoze.lru
,安装在/usr/lib/python2.7/dist-packages/
My problem is that it does not work on the replicated system: the application fails to import repoze.who
.我的问题是它在复制系统上不起作用:应用程序无法导入repoze.who
。 On the other hand, on the original system, it works file and successfully imports both subpackages.另一方面,在原始系统上,它可以运行文件并成功导入两个子包。
I understand that it's not supposed to work since, in normal configuration, Python does not expect a package to be split in several places.我知道它不应该工作,因为在正常配置中, Python 不希望 package 在几个地方拆分。
I read the python import different subpackages with the same root packge name and different locations question and its answer.我阅读了python import different subpackages with the same root packge name and different locations问题及其答案。 If I modify both repoze/__init__.py
files as suggested, it works fine on the replicated system.如果我按照建议修改两个repoze/__init__.py
文件,它在复制系统上工作正常。
But I checked both files on the original system, and they are empty.但是我在原来的系统上检查了两个文件,它们都是空的。
I added a few print
instructions in the WSGI application, to investigate the original system.我在 WSGI 应用程序中添加了一些print
指令,以调查原始系统。 sys.path
looks fine and similar on both systems, with /usr/lib/python2.7/dist-packages
before /usr/lib/pymodules/python2.7
on both. sys.path
在两个系统上看起来都不错且相似,/usr/lib/python2.7/ /usr/lib/pymodules/python2.7
在/usr/lib/python2.7/dist-packages
之前。 Surprisingly, the repoze
package is imported from /usr/lib/pymodules/python2.7
on the original system, while it is imported from /usr/lib/python2.7/dist-packages
on the replicated system.令人惊讶的是, repoze
package 是从原始系统上的/usr/lib/pymodules/python2.7
导入的,而它是从复制系统上的/usr/lib/python2.7/dist-packages
导入的。 Moreover, repoze.__path__
contains both locations on the original system, while it only contains /usr/lib/python2.7/dist-packages/repoze
on the replicated system.此外, repoze.__path__
包含原始系统上的两个位置,而它仅包含/usr/lib/python2.7/dist-packages/repoze
在复制系统上。
Last but not least, if I run the virtualenv's python interpreter on the original system, it fails to import the repoze.who
package while it imports repoze.lru
file, which looks like a normal behaviour.最后但同样重要的是,如果我在原始系统上运行 virtualenv 的 python 解释器,它在导入repoze.lru
文件时无法导入repoze.who
package,这看起来是正常行为。 Hence, there must be something special with mod-wsgi or the application.因此,mod-wsgi 或应用程序必须有一些特殊之处。
I guess something “clever” was done to allow the WSGI application to load both packages from different locations, but I have no idea what.我猜想做了一些“聪明”的事情来允许 WSGI 应用程序从不同的位置加载两个包,但我不知道是什么。 Any suggestion is welcome.欢迎任何建议。
repoze
is using namespace packages . repoze
正在使用命名空间包。
From its setup.py
:从它的setup.py
:
namespace_packages=['repoze', 'repoze.who', 'repoze.who.plugins'],
pkgutil
approach when you need compatibility with existing code already using that approach.当您需要与已经使用该方法的现有代码兼容时,请参阅pkgutil
方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.