问题:如何离开/退出/停用Python virtualenv
我正在使用virtualenv和virtualenvwrapper。我可以使用workon
命令在virtualenv之间切换。
me@mymachine:~$ workon env1
(env1)me@mymachine:~$ workon env2
(env2)me@mymachine:~$ workon env1
(env1)me@mymachine:~$
如何退出所有虚拟机并再次在真实计算机上工作?现在,我唯一要回到的方法me@mymachine:~$
是退出外壳并启动一个新外壳。真烦人。有没有什么要执行的命令,如果是的话,这是什么?如果这样的命令不存在,我将如何创建它?
I’m using virtualenv and the virtualenvwrapper. I can switch between virtualenv’s just fine using the workon
command.
me@mymachine:~$ workon env1
(env1)me@mymachine:~$ workon env2
(env2)me@mymachine:~$ workon env1
(env1)me@mymachine:~$
How do I exit all virtual machines and work on my real machine again? Right now, the only way I have of getting back to me@mymachine:~$
is to exit the shell and start a new one. That’s kind of annoying. Is there a command to work on “nothing”, and if so, what is it? If such a command does not exist, how would I go about creating it?
回答 0
通常,激活virtualenv会给您提供一个名为:
$ deactivate
这使情况恢复正常。
我只是再次专门查看的代码virtualenvwrapper
,是的,它也支持deactivate
从所有virtualenvs逃脱的方式。
如果您要离开Anaconda环境,则该命令取决于您的的版本conda
。最新版本(如4.6)conda
直接在您的shell中安装一个函数,在这种情况下,您可以运行:
conda deactivate
较旧的conda版本改为使用独立脚本实现停用:
source deactivate
Usually, activating a virtualenv gives you a shell function named:
$ deactivate
which puts things back to normal.
I have just looked specifically again at the code for virtualenvwrapper
, and, yes, it too supports deactivate
as the way to escape from all virtualenvs.
If you are trying to leave an Anaconda environment, the command depends upon your version of conda
. Recent versions (like 4.6) install a conda
function directly in your shell, in which case you run:
conda deactivate
Older conda versions instead implement deactivation using a stand-alone script:
source deactivate
回答 1
我所定义的别名,workoff,作为相反workon:
alias workoff='deactivate'
很容易记住:
[bobstein@host ~]$ workon django_project
(django_project)[bobstein@host ~]$ workoff
[bobstein@host ~]$
I defined an alias, workoff, as the opposite of workon:
alias workoff='deactivate'
It is easy to remember:
[bobstein@host ~]$ workon django_project
(django_project)[bobstein@host ~]$ workoff
[bobstein@host ~]$
回答 2
采用:
$ deactivate
如果这不起作用,请尝试
$ source deactivate
任何知道Bash的source
工作原理的人都会认为这很奇怪,但是围绕virtualenv的一些包装器/工作流将其实现为对Bash的补充/对应source activate
。你的旅费可能会改变。
Use:
$ deactivate
If this doesn’t work, try
$ source deactivate
Anyone who knows how Bash source
works will think that’s odd, but some wrappers/workflows around virtualenv implement it as a complement/counterpart to source activate
. Your mileage may vary.
回答 3
要激活Python虚拟环境:
$cd ~/python-venv/
$./bin/activate
停用:
$deactivate
To activate a Python virtual environment:
$cd ~/python-venv/
$./bin/activate
To deactivate:
$deactivate
回答 4
我发现在Miniconda3环境中时,我必须运行:
conda deactivate
既deactivate
没有source deactivate
为我工作,也没有为我工作。
I found that when within a Miniconda3 environment I had to run:
conda deactivate
Neither deactivate
nor source deactivate
worked for me.
回答 5
您可以使用virtualenvwrapper
来简化您的使用方式virtualenv
。
安装virtualenvwrapper
:
pip install virtualenvwrapper
如果您使用的是标准外壳,请打开~/.bashrc
或~/.zshrc
使用Oh My Zsh。添加这两行:
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
要激活现有的virtualenv,请使用命令workon
:
$ workon myenv
(myenv)$
为了停用您的virtualenv:
(myenv)$ deactivate
这是我的教程,逐步介绍了如何安装virtualenv和virtualenvwrapper。
You can use virtualenvwrapper
in order to ease the way you work with virtualenv
.
Installing virtualenvwrapper
:
pip install virtualenvwrapper
If you are using a standard shell, open your ~/.bashrc
or ~/.zshrc
if you use Oh My Zsh. Add these two lines:
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh
To activate an existing virtualenv, use command workon
:
$ workon myenv
(myenv)$
In order to deactivate your virtualenv:
(myenv)$ deactivate
Here is my tutorial, step by step on how to install virtualenv and virtualenvwrapper.
回答 6
由于无法通过寻找这种命令的常用方法来发现deactivate
通过源创建的功能,因此您可能希望创建一个仅执行该功能的命令。~/bin/activate
~/bin
deactivate
问题是,如果一个脚本名叫deactivate
包含单个命令,则该脚本deactivate
如果不在venv中意外执行,将导致无限循环。一个常见的错误。
通过仅deactivate
在函数存在时执行(即已通过source创建activate
),可以避免这种情况。
#!/bin/bash
declare -Ff deactivate && deactivate
Since the deactivate
function created by sourcing ~/bin/activate
cannot be discovered by the usual means of looking for such a command in ~/bin
, you may wish to create one that just executes the function deactivate
.
The problem is that a script named deactivate
containing a single command deactivate
will cause an endless loop if accidentally executed while not in the venv. A common mistake.
This can be avoided by only executing deactivate
if the function exists (i.e. has been created by sourcing activate
).
#!/bin/bash
declare -Ff deactivate && deactivate
回答 7
使用deactivate
。
(my_env) user@user:~/my_env$ deactivate
user@user-Lenovo-E40-80:~/my_env$
注意,(my_env)
不见了。
Use deactivate
.
(my_env) user@user:~/my_env$ deactivate
user@user-Lenovo-E40-80:~/my_env$
Note, (my_env)
is gone.
回答 8
我使用基于autoenv的zsh- autoenv。
zsh-autoenv自动获取(已知/列入白名单的).autoenv.zsh
文件,通常在项目根目录中使用。它处理“进入”和“离开”事件,变量的嵌套和隐藏(覆盖和还原)。
这是一个例子:
; cd dtree
Switching to virtual environment: Development tree utiles
;dtree(feature/task24|✓); cat .autoenv.zsh
# Autoenv.
echo -n "Switching to virtual environment: "
printf "\e[38;5;93m%s\e[0m\n" "Development tree utiles"
workon dtree
# eof
dtree(feature/task24|✓); cat .autoenv_leave.zsh
deactivate
因此,当我离开dtree
目录时,虚拟环境将自动退出。
"Development tree utiles"
只是一个名字而已。
I use zsh-autoenv which is based off autoenv.
zsh-autoenv automatically
sources (known/whitelisted) .autoenv.zsh
files, typically used in
project root directories. It handles “enter” and leave” events,
nesting, and stashing of variables (overwriting and restoring).
Here is an example:
; cd dtree
Switching to virtual environment: Development tree utiles
;dtree(feature/task24|✓); cat .autoenv.zsh
# Autoenv.
echo -n "Switching to virtual environment: "
printf "\e[38;5;93m%s\e[0m\n" "Development tree utiles"
workon dtree
# eof
dtree(feature/task24|✓); cat .autoenv_leave.zsh
deactivate
So when I leave the dtree
directory, the virtual environment is automatically exited.
"Development tree utiles"
is just a name… No hidden mean linking to the Illuminati in here.
回答 9
使用deactivate
venv activate
脚本提供的功能,您需要信任正确激活了禁用功能的代码,才能将所有环境变量完全重置为以前的状态-不仅要考虑原始激活,还要考虑所有开关,配置或其他在此期间您可能已经完成的工作。
可能很好,但是确实会带来一种新的,非零的风险,即事后修改环境。
但是,从工艺上讲,直接更改其父级的环境变量在技术上是不可能的,因此我们可以使用单独的子外壳来确保我们venv
的进程不会留下任何残留更改:
激活:
$ bash --init-file PythonVenv/bin/activate
- 这将在周围启动一个新的shell
venv
。您原来的bash
外壳保持不变。
停用:
$ exit
或[CTRL]
+[D]
- 这将退出整个外壳
venv
,并使您回到激活脚本对环境进行任何更改之前的原始外壳。
例:
[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!
[user@computer ~]$ bash --init-file PythonVenv/bin/activate
(PythonVenv) [user@computer ~]$ echo $VIRTUAL_ENV
/home/user/PythonVenv
(PythonVenv) [user@computer ~]$ exit
exit
[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!
Using the deactivate
feature provided by the venv’s activate
script requires you to trust the deactivation function to be properly coded to cleanly reset all environment variables back to how they were before— taking into account not only the original activation, but also any switches, configuration, or other work you may have done in the meantime.
It’s probably fine, but it does introduce a new, non-zero risk of leaving your environment modified afterwards.
However, it’s not technically possible for a process to directly alter the environment variables of its parent, so we can use a separate sub-shell to be absolutely sure our venv
s don’t leave any residual changes behind:
To activate:
$ bash --init-file PythonVenv/bin/activate
- This starts a new shell around the
venv
. Your original bash
shell remains unmodified.
To deactivate:
$ exit
OR [CTRL]
+[D]
- This exits the entire shell the
venv
is in, and drops you back to the original shell from before the activation script made any changes to the environment.
Example:
[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!
[user@computer ~]$ bash --init-file PythonVenv/bin/activate
(PythonVenv) [user@computer ~]$ echo $VIRTUAL_ENV
/home/user/PythonVenv
(PythonVenv) [user@computer ~]$ exit
exit
[user@computer ~]$ echo $VIRTUAL_ENV
No virtualenv!
回答 10
在处理安装程序脚本时,我遇到了同样的问题。我看了一下bin / activate_this.py做了什么,并将其反转了。
例:
#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
# Path to virtualenv
venv_path = os.path.join('/home', 'sixdays', '.virtualenvs', 'test32')
# Save old values
old_os_path = os.environ['PATH']
old_sys_path = list(sys.path)
old_sys_prefix = sys.prefix
def deactivate():
# Change back by setting values to starting values
os.environ['PATH'] = old_os_path
sys.prefix = old_sys_prefix
sys.path[:0] = old_sys_path
# Activate the virtualenvironment
activate_this = os.path.join(venv_path, 'bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
# Print list of pip packages for virtualenv for example purpose
import pip
print str(pip.get_installed_distributions())
# Unload pip module
del pip
# Deactivate/switch back to initial interpreter
deactivate()
# Print list of initial environment pip packages for example purpose
import pip
print str(pip.get_installed_distributions())
我不确定100%是否能按预期工作。我可能完全错过了一些东西。
I had the same problem while working on an installer script. I took a look at what the bin/activate_this.py did and reversed it.
Example:
#! /usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
# Path to virtualenv
venv_path = os.path.join('/home', 'sixdays', '.virtualenvs', 'test32')
# Save old values
old_os_path = os.environ['PATH']
old_sys_path = list(sys.path)
old_sys_prefix = sys.prefix
def deactivate():
# Change back by setting values to starting values
os.environ['PATH'] = old_os_path
sys.prefix = old_sys_prefix
sys.path[:0] = old_sys_path
# Activate the virtualenvironment
activate_this = os.path.join(venv_path, 'bin/activate_this.py')
execfile(activate_this, dict(__file__=activate_this))
# Print list of pip packages for virtualenv for example purpose
import pip
print str(pip.get_installed_distributions())
# Unload pip module
del pip
# Deactivate/switch back to initial interpreter
deactivate()
# Print list of initial environment pip packages for example purpose
import pip
print str(pip.get_installed_distributions())
I am not 100% sure if it works as intended. I may have missed something completely.