有没有办法在Python解释器中停用virtualenv?即类似deactivate_this的功能

4 投票
2 回答
1295 浏览
提问于 2025-04-18 18:54

我有一个脚本(这是一个用于openshift应用的wsgi脚本的开头部分)。这个脚本通过Python系统环境来激活一个虚拟环境。

#!/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

那相反的情况呢?也就是说,有没有类似于“deactivate_this”的方法?(我创建的虚拟环境中似乎没有这样的文件)

这意味着:我不想重新发明轮子。我是在问是否有现成的命令可以做到这一点。

2 个回答

2

这是对@TomDalton回答的补充。虽然没有自动提供的方法来做到这一点,但可以通过activate_this脚本来实现。

首先,重要的是要记住这一行:

execfile(virtualenv, dict(__file__=virtualenv))

这行代码是在调用一个函数,但没有传递任何全局变量或局部变量的字典。这意味着执行的上下文将是当前的全局变量(也就是调用这一行时的全局变量)和局部变量对象。这样的代码会改变我们当前的变量——会覆盖调用环境中的变量 详细信息请查看这里

因此,由于变量被覆盖,activate_this提供了一些变量,比如:

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

所以如果我们想手动停用这些变量,可以恢复它们:

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)
3

我认为简单的回答是“不可以”。

稍微复杂一点的回答是:“除非你在执行activate_this.py之前保存了环境的状态,否则不行。”

或许你想要的解决办法是,把需要在虚拟环境(venv)中运行的部分和不需要的部分分开。然后可以用一个子进程来激活虚拟环境,运行你想要的东西。当这个子进程结束后,你原来的进程(在原始环境中)可以继续运行。

另外,这篇帖子(如何离开/退出/停用Python虚拟环境?)提到激活可能会提供一个shell功能来恢复一切。你需要检查一下你的activate_this.py脚本是否提供类似的功能,不过听起来你已经检查过了。

撰写回答