Python动态导入无法在Virtualenv中查找包

时间:2015-07-24 04:24:08

标签: 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)时,库导入就好了。打开shell并手动导入库时,它可以正常工作。

但是,当运行main.py并动态导入b.py时(使用pkgutil.iter_modules检测模块,然后importlib.import_module导入所需的模块),库<{1}}导入未找到 - b.py被抛出。

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

2 个答案:

答案 0 :(得分:1)

第三个不相关的细节是问题: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

也可以通过使用/usr/lib/python2.7/site-packages将安装位置(在我的情况下,sys.path.append)附加到python路径来解决这个问题,但这种情况很糟糕,并且可能导致其他人的问题。

答案 1 :(得分:0)

Virtualenvs臭名昭着。他们多次修补路径并搞砸了很多东西。

在两种情况下,您都需要检查PATH内的b.py变量。 这很可能不一样。

您需要设置包含c.py目录的路径。 您可以在main.py中查看PATH,如果它在那里是正确的,则表示您的其他导入之一正在更改sys.path以便删除它。