Python动态导入在Virtualenv中找不到包

标签 python python-2.7 python-import

所以,我有一个目录结构:

main.py
\_ modules/
   \_ a.py
   \_ b.py

在 main.py 中,模块在运行时动态加载,具体取决于指定的模块。 (这允许添加假设的 c.py,重新运行 main.py,以及程序检测 c.py 的添加并运行它。)

问题是 b.py导入通过 pip 安装的模块(在 virtualenv 中)。 (我将把它称为一个库,以避免混淆。)当 b.py直接运行( python b.py )库导入就好了。当外壳打开并手动导入库时,它就可以工作。

但是,当 main.py运行并 b.py动态导入(使用 pkgutil.iter_modules 检测模块,然后 importlib.import_module 导入所需的模块), b.py 的库找不到导入 - ImportError: No module被抛出。

回顾一下:模块导入已安装的库,当直接运行模块或在 python 解释器中手动导入有问题的库时,这是有效的,但是当动态导入模块时,找不到该库。给出了什么?

最佳答案

第三个不相关的细节是问题:pyenv。

有一个错误报告 here ,但长话短说是 pyenv 使用垫片来拦截包导入并正确路由它们。

这意味着 pyenv 必须混淆路径。当我直接运行 python 时,填充程序在 python 路径中很明显:

[dnelson@blueharvest somedir]$ python
Python 2.7 (r27:82500, Jun  1 2015, 15:01:57) 
[GCC 4.9.2 20150212 (Red Hat 4.9.2-6)] on linux3
Type "help", "copyright", "credits" or "license" for more information.
>>> import site
>>> site.getsitepackages()
['/home/dnelson/.pyenv/versions/2.7/lib/python2.7/site-packages', '/home/dnelson/.pyenv/versions/2.7/lib/site-python']
>>> site.PREFIXES
['/home/dnelson/.pyenv/versions/2.7', '/home/dnelson/.pyenv/versions/2.7']
>>> 

但是,在动态导入的包中,相同的代码会产生以下输出:

['/usr/lib64/python2.7/site-packages', '/usr/lib/python2.7/site-packages', '/usr/lib/site-python']
['/usr', '/usr']

因此,问题似乎是 pyenv 在动态导入期间没有发挥其垫片魔力。

为了解决这个问题,我使用 pip install --user 强制 pip 安装到动态导入所查找的位置,而不是 pyenv 希望安装的位置。 (如果您之前安装过该软件包,还可以添加 -I 以强制重新安装)

也可以通过使用 sys.path 将安装位置(在我的例子中为 /usr/lib/python2.7/site-packages)附加到 python 路径来解决。附加,但这闻起来很糟糕,并且可能会给其他人带来问题。

关于Python动态导入在Virtualenv中找不到包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31602160/

相关文章:

python - 按唯一组的数量对 Pandas 列进行排序

python - cv2.imshow 和 cv2.imwrite

python - 属性错误: 'NodeView' object has no attribute 'index'

python - 从另一个包导入 Cython 头文件

python - "ImportError: No module named..."导入我自己的模块时

python - 使用python高效绘制线条

python-2.7 - 数据交换——Python 和 Fortran

python - 此列表代码的追加和连接的复杂性差异?

python - python中的全局数组打印

python - 在python中获取导入模块的有序列表