如何在不激活virtualenv的情况下在virtualenv中查找模块?

问题描述:

假设我有以下设置:如何在不激活virtualenv的情况下在virtualenv中查找模块?

mkdir test && cd test 
virtualenv .venv 
source .venv/bin/activate 
pip install django 
mkdir mod1 
touch mod1/__init__.py 
echo "a = 1" > mod1/mod2.py 

这给了我:

test/.venv 
test/mod1/__init__.py 
test/mod1/mod2.py 

我怎么会写这样的功能:

def get_module(module_name, root_path, virtualenv_path=None) 

为了这个工作:

project_root_path = "./test" 
project_virtualenv_path = "./test/.venv" 

get_module("mod1.mod2", project_root_path, project_virtualenv_path) 
get_module("django.contrib.auth", project_root_path, project_virtualenv_path) 

假设我没有./test/.venv激活。

我想这样做的原因是因为我正在使用一个vim插件,它将在导入语句的python文件中实现gf的功能。我也试图支持virtualenvs。

编辑:

此外,脚本应该不会改变当前的运行时,通过添加或追加到sys.path中。这应该在vim中通过vim python绑定运行,并且我不认为改变vim python运行时会是一个好主意。

get_module可以返回一个模块对象,或模块的路径,这正是我基本寻找的。

唯一可行的解​​决方案,我能找到这里是运行的virtualenv的activate_this.py剧本,找我需要,然后从sys.path删除它的变化。

import sys 
import os 

old_sys_path = list(sys.path) 

virtualenv_path = "/path/to/venv" 
activate_this_path = os.path.join(virtualenv_path, "bin", "activate_this.py") 

execfile(activate_this_path, dict(__file__=activate_this_path)) 

# get my module here 

# restore sys.path 
sys.path = old_sys_path 

如果你有更好的答案,请添加它,我会很乐意改变接受的答案。

可以蟒蛇路径上添加你的virtualenv这样的:

import site 
site.addsitedir('/home/user/.virtualenvs/myapp1/lib/python2.7/site-packages') 

然后导入应该工作

+0

有两个问题:** 1)**它改变了运行时间,这是不好的(sry,用解释编辑了问题)** 2)**它只包含站点包,假设我想要一个安装在'.test/.venv/src /'中的软件包,通常是这种情况。谢谢你的回答。 – Prody 2012-07-13 13:44:08

+0

似乎当pip在'./test/ .venv/src /'中安装一个包时,它会在'site-packages'中创建一个'egg-link',并且'site'模块知道如何添加它。所以** 2)**不是问题。 – Prody 2012-07-13 14:19:17