Python动态导入可以';在Virtualenv中找不到包

Python动态导入可以';在Virtualenv中找不到包,python,python-2.7,python-import,Python,Python 2.7,Python Import,因此,我有一个目录结构: main.py \_ modules/ \_ a.py \_ b.py 在main.py中,根据指定的模块,在运行时动态加载模块。(这允许添加一个假设的c.py,重新运行main.py,程序检测c.py的添加并运行它。) 问题在于b.py导入通过pip(在虚拟环境中)安装的模块。(为了避免混淆,我将把它称为一个库。)当直接运行b.py(python b.py)时,库导入就可以了。打开shell并手动导入库时,它会工作 但是,当运行main.py并动态导入b

因此,我有一个目录结构:

main.py
\_ modules/
   \_ a.py
   \_ b.py
在main.py中,根据指定的模块,在运行时动态加载模块。(这允许添加一个假设的
c.py
,重新运行
main.py
,程序检测
c.py
的添加并运行它。)

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

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


概括地说:模块导入已安装的库,当模块直接运行或在python解释器中手动导入有问题的库时,这会起作用,但当模块动态导入时,找不到库。有什么好处?

虚拟人是臭名昭著的。他们多次在小路上修修补补,弄得乱七八糟

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

您需要设置包含
c.py
目录的路径。
您可以在
main.py
中检查路径,如果路径正确,则意味着其他导入之一正在以删除路径的方式更改您的
sys.PATH

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

有一个bug报告,但长话短说,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.append
将安装位置(在我的例子中是
/usr/lib/python2.7/site packages
)附加到python路径来解决,但这闻起来很难闻,可能会给其他人带来问题。

这不是很正确的答案,但它让我走上了正确的道路。非常感谢。向下投票解释:“Virtualenvs是臭名昭著的。他们多次修补路径,把很多事情搞糟。”-Virtualenvs有明确的行为,现在是主要发行版的一部分。它们确实会影响路径,但“修补”/“弄乱”读起来就像它们产生了意想不到的魔力——这是不正确的。