简体   繁体   English

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

[英]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'],
  • See PEP 420 for the modern way to build namespace packages.有关构建命名空间包的现代方法,请参阅PEP 420
  • See pkg_resources for the old way (the approach I have personal experience with, back in the mid-2000s).请参阅pkg_resources了解旧方法(我在 2000 年代中期亲身体验过的方法)。
  • See the pkgutil approach when you need compatibility with existing code already using that approach.当您需要与已经使用该方法的现有代码兼容时,请参阅pkgutil方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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