如何离开/退出/停用Python virtualenv

问题:如何离开/退出/停用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~/bindeactivate

问题是,如果一个脚本名叫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

使用deactivatevenv 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 venvs 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.