有没有办法在python解释器中停用virtualenv?也就是说,类似于停用

Is there a way to deactivate a virtualenv inside python interpreter? i.e. analogous of deactivate_this

我有这个脚本(这是OpenSHIFT应用程序的WSGI脚本的开始)。此脚本使用in-python系统环境激活virtualenv。

1
2
3
4
5
6
7
8
9
#!/usr/bin/python
import os

virtenv = os.environ['OPENSHIFT_PYTHON_DIR'] + '/virtenv/'
virtualenv = os.path.join(virtenv, 'bin/activate_this.py')
try:
    execfile(virtualenv, dict(__file__=virtualenv))
except IOError:
    pass

相反的是什么?例如:有没有类似的方法来"停用这个"?(这样的文件似乎在我创建的任何virtualenv中都不存在)

这意味着:我不想重新发明轮子。我在问是否有一个准备好的命令行。


我相信简短的回答是不。

中等回答是"除非在执行activate_this.py之前保存了环境的状态,否则不会"。

也许实现你想要的是将你的应用程序中需要在venv中运行的部分与不需要在venv中运行的部分分开。然后使用子进程激活venv并运行你想要的任何内容,当子进程终止时,你的原始进程(在原始环境中)可以恢复。

注意这篇文章(如何离开/退出/停用python virtualenv?)建议激活可以提供一个shell函数来恢复所有内容。您需要检查您的activate_this.py脚本是否提供了类似的内容,尽管听起来您已经检查过了这一点。


这是对Tomdalton给出的答案的补充。尽管没有自动提供的方法来实现这一点,但activate_this脚本提供了一些方法。

首先,记住这一行很重要:

1
execfile(virtualenv, dict(__file__=virtualenv))

调用函数时,不传递全局变量的字典,也不传递局部变量的字典。这意味着执行上下文将是当前全局对象(即来自调用行的全局对象)和局部对象。这样的行将改变我们当前拥有的变量——将覆盖调用环境,请参阅此处获取关于的文档。

这样,由于变量被覆盖,activate_this给了我们一些变量,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
old_os_path = os.environ['PATH']
#the previous PATH

prev_sys_path = list(sys.path)
#the old Python Path

if sys.platform == 'win32':
    site_packages = os.path.join(base, 'Lib', 'site-packages')
else:
    site_packages = os.path.join(base, 'lib', 'python%s' % sys.version[:3], 'site-packages')
prev_sys_path = list(sys.path)
import site
site.addsitedir(site_packages)
#site_packages is the extended venv's packages dir.
#sys.path is affected here

sys.real_prefix = sys.prefix
#the old system prefix

因此,如果需要手动停用,我们可以恢复这些变量:

1
2
3
4
import sys, os, site
sys.path[:0] = prev_sys_path #will also revert the added site-packages
sys.prefix = sys.real_prefix
os.setenv('PATH', old_os_path)