有没有办法在 python 解释器中停用 virtualenv?即类似于 deactivate_this
Posted
技术标签:
【中文标题】有没有办法在 python 解释器中停用 virtualenv?即类似于 deactivate_this【英文标题】:Is there a way to deactivate a virtualenv inside python interpreter? i.e. analogous of deactivate_this 【发布时间】:2014-10-22 22:08:51 【问题描述】:我有这个脚本(这是用于 openshift 应用程序的 wsgi 脚本的开始)。此脚本使用 in-python 系统环境激活 virtualenv。
#!/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”? (我创建的任何虚拟环境中似乎都不存在这样的文件)
这意味着:我不想重新发明***。我在问是否有为此准备好的命令行。
【问题讨论】:
你试过子进程吗? 其实,没有。这是否让我也可以更改环境变量? 你只是想停用 virtualenv 是吗? 是的。这个脚本 (activate_this) 改变了环境和底层的 shell。有没有现成的方法来做相反的事情? 导致问题的激活设置具体是什么?如果使用 mod_wsgi,还有其他激活虚拟环境的方法。因此,帮助我们了解最初的问题是什么比问我们您认为解决方案是什么要好。 【参考方案1】:我相信简短的回答是否定的。
中等答案是“除非你在执行 activate_this.py 之前保存了环境的状态”。
也许实现您想要的一种方法是将应用程序中需要在 venv 中运行的部分与不需要的部分分开。然后使用子进程激活venv并运行你想要的任何东西,当子进程终止时,你的原始进程(在原始环境中)可以恢复。
NB 这篇文章 (How to leave/exit/deactivate a python virtualenv?) 表明激活可能会提供一个 shell 函数来将所有东西都放回去。您需要检查您的 activate_this.py
脚本是否提供了类似的功能,尽管听起来您已经检查过了。
【讨论】:
我接受你的回答(它符合我的要求),并用我现在发现的内容添加我的答案。 谢谢 - 听起来很有趣! 如果你有一天遇到这样的问题,它就在那里 :)。【参考方案2】:这是对@TomDalton 给出的答案的补充。尽管没有自动提供的方法来执行此操作,但activate_this
脚本提供了一些方法。
首先,重要的是要记住这一行:
execfile(virtualenv, dict(__file__=virtualenv))
调用函数时没有传递全局字典或本地字典。这意味着执行上下文将是当前的全局对象(即来自调用行的那个)和本地对象。 这样的行将改变我们当前拥有的变量——将覆盖调用环境See here for docs about。
这样,由于变量被覆盖,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)
【讨论】:
不错。很遗憾 activate_this.py 没有提供自动执行此操作的功能,但我认为它不是为这项工作而设计的。 activate_this 专门为此目的而设计(否则脚本将不存在)。我认为推荐具有这种功能的补丁(这是一个不间断的补丁)是明智的。我现在正在尝试。 对不起,我的意思是能够停用环境。如果它是为此而设计的,那么期望您使用上面找到的命令是不明显的,并且似乎没有在任何地方记录。 我没有正确表达自己。activate_this
旨在在相同的 python 路径中运行。扩展它以创建 deactivate
函数很简单。遗憾的是,这些变量没有记录在案,因此可以更改,恕不另行通知。以上是关于有没有办法在 python 解释器中停用 virtualenv?即类似于 deactivate_this的主要内容,如果未能解决你的问题,请参考以下文章
如何在flutter中停用或覆盖appBar中的箭头后退按钮?