123

这个问题不是重复的。

它不仅涉及重命名虚拟环境,还涉及将其实际移动到不同的目录,包括可能的不同用户的目录。

这与仅仅重命名虚拟环境不同,尤其是对于不熟悉 virtualenvs 的人。

如果我创建了一个 virtualenv,并将它移到另一个文件夹,它还能工作吗?

$ virtualenv -p /usr/bin/python3 /home/me/Env/my-python-venv
$ source Env/my-python-venv/bin/activate
(my-python-venv) $ 

...那天晚些时候,虚拟环境移动了...

(my-python-venv) $ deactivate
$ mkdir -p /home/me/PeskyPartyPEnvs
$ mv /home/me/Env/my-python-venv /home/me/PeskyPartyPEnvs/

问题:

这行得通吗?

$ source /home/me/PeskyPartyPEnvs/my-python-venv/bin/activate
(my-python-venv) $ /home/me/PeskyPartyPEnvs/my-python-venv/bin/pip3 install foaas

我的意思是,这不是关于尝试这样做的智慧的问题(当然,除非智慧是幽默的),而更多的是关于它是否可能。我真的很想知道是否可以在 Python 3 中完成,或者我是否只需将其吸收并克隆它。

我可以mvvirtualenv那样没有悲伤吗?我确实想避免悲伤。

4

9 回答 9

80

是的。可以在同一平台上移动它。您可以--relocatable在现有环境中使用。

来自--help

--relocatable -- 使现有的 virtualenv 环境可重定位。这修复了脚本并使所有 .pth 文件相对。

但是,这似乎不会更改activate脚本,而只会更改pip*easy_install*脚本。在activate脚本中, $VIRTUAL_ENV环境变量硬编码为原始/path/to/original/venv. 该$VIRTUAL_ENV变量也用于设置PATH您的活动环境,因此必须根据新位置更改它以便在没有绝对路径的情况下调用等pythonpip

要解决此问题,您可以更改脚本$VIRTUAL_ENV中的环境变量activate(例如使用sed),一切都应该很好。

使用示例:

$ cd ~/first
$ virtualenv my-venv
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV="/home/username/first/my-venv"
$ virtualenv --relocatable my-venv
Making script my-venv/bin/easy_install relative
Making script my-venv/bin/easy_install-2.7 relative
Making script my-venv/bin/pip relative
Making script my-venv/bin/pip2 relative
Making script my-venv/bin/pip2.7 relative
### Note that `activate` has not been touched
$ mkdir ~/second
$ mv my-venv ~/second
$ cd ~/second
$ grep 'VIRTUAL_ENV=' my-venv/bin/activate
VIRTUAL_ENV=/home/username/first/my-venv
### (This variable hasn't been changed, it still refers to the old, now non-existent directory!)
$ sed -i -e 's|username/first|username/second|' my-venv/bin/activate
## sed can be used to change the path.
## Note that the `-i` (in place) flag won't work on all machines. 
$ source my-venv/bin/activate 
(my-venv) $ pip install foass
...
(my-venv) $ python 
[...]
> import foass

万岁,现在您可以安装东西并将它们加载到新定位的虚拟环境中。

于 2015-09-05T01:31:44.557 回答
50

对于 Python 3.3+(带有新venv的内置模块)

简短答案(无论版本如何):

  • 没有干净、直接的方法来移动虚拟环境
  • 只需重新创建,这很容易!


长答案:

从 Python v3.3 开始,virtualenv已成为一个名为venv.

其他答案中提到的--relocatable选项未包含在 中venv,目前我知道没有好的、安全的方法可以重命名或重新定位 Python 虚拟环境。

但是,使用所有当前安装的包重新创建一个虚拟环境是相当简单的。请参阅此答案,或参阅以下部分。在此过程中,您可以在任何位置以您想要的任何名称重新创建新环境。

在上面链接的答案中,他提到了一些可能支持直接重命名或移动的第三方包。如果您决定寻求一种移动虚拟环境的方法,您可以研究这些方法是否也可以使用venv

注意:在那个答案中,它的重点是virtualenv,而不是venv。有关如何翻译,请参阅下一节。



venv与旧的virtualenv命令语法

要使用的命令venv是:

python -m venv

而不仅仅是virtualenv,它作为命令安装在原始包中。“python”指的是你运行你的python可执行文件的地方,它可能是各种各样的东西,例如:

  1. python
  2. pypy -3.7或类似的(目前仅适用于 Python 3.3+ 和 Windows的Python 启动器)
  3. python3(双重安装 python 2 和 3 的 linux 环境的约定)
  4. 如果遇到问题,请使用要运行的 python 可执行文件的绝对路径:例如c:\program files\python37\python.exe

如果您不确定正在运行哪个版本,您可以随时python --version查找。



如何重新创建虚拟环境

创建/重新创建虚拟环境很容易,并且在您使用它们一段时间后应该成为第二天性。此过程反映了您在前半部分将脚本作为包(及其依赖项)分发时所做的事情,然后有人会为进一步开发而安装您的脚本/包所做的事情。

首先,获取虚拟环境中内容的更新列表。激活它后,获取它使用的 Python 版本并将依赖项列表保存到文件中。

  1. 与激活的虚拟环境一起使用python --version以查看它正在使用的 Python 版本。

    • 这是为了清楚起见 - 您可能出于各种原因想要更新 Python 版本 - 至少到最新的补丁版本
    • 例如,如果现有的 venv 使用的是 Python v3.7.4,但现在 v3.7.6 已经过时 - 请改用 v3.7.6,它应该只包括非破坏性安全性和错误修复。
  2. 用于python -m pip freeze > requirements.txt创建当前包依赖项列表并将它们放入requirements.txt文件中。这个命令肯定可以在 Linux 或 Git Bash 中工作 - 不能 100% 确定 Windows 中的 Powershell 或命令行。

现在创建一个新的虚拟环境,然后添加旧的依赖项。

  1. 做你的新venv。

    • 确保您使用的是要安装到 venv 的正确版本的 python。
    • 如果您希望它是完全相同的 Python 版本:
      • 直接从当前虚拟环境(激活它)运行 python,并python作为命令使用
      • python.exe或者在虚拟环境文件夹中使用绝对路径
    • 对于命令中的新 venv 文件夹条目:
      • 将绝对或相对路径添加到所需的最终文件夹位置。
      • 用于在当前工作目录中的新文件夹python -m venv my_new_venv中创建新的虚拟环境。my_new_venv
      • venv 文件夹的名称将是 venv 的名称(激活时提示中显示的名称)。
  2. requirements.txt文件中安装您的依赖项。

    • python -m pip install -r requirements.txt

您可能需要重新安装处于开发模式的本地软件包。

请注意,如果您需要查看软件包安装到的特定位置,请使用:

  • python -m pip list -v
  • 或“-v详细”选项将添加有关已安装的每个软件包的一些额外信息,包括它的安装路径。这有助于确保您保持虚拟、用户和系统安装的软件包直截了当。

此时您可以删除旧的 venv 文件夹和所有内容。我建议为此使用 GUI - 从 linux 命令行删除文件通常是永久性的,一个小的错字可能是坏消息。

于 2019-11-08T18:37:54.250 回答
14

可惜:

不,你不能简单地mv。有解决方法,但重新安装可能更容易。

(my-python-venv)$ /home/me/PeskyPartyPEnvs/pip3 install foaas
zsh: /home/me/PeskyPartyPEnvs/pip3: bad interpreter: /home/me/Env/my-python-venv/bin/python3: no such file or directory
(my-python-venv)$ deactivate
$ 

...沮丧地按下enter了很多,并且以下作品

$
$
$ pip3 search foaas

除非它不是来自my-python-venv,所以悲伤。

想要mv你的virtualenv并使用它,否则未经修改?

简短的回答:

我会让波罗米尔说出来,这样他才能说清楚:

好吧,你不能

于 2015-09-04T22:27:06.580 回答
8

--relocatable论点virtualenv似乎允许您这样做。

于 2015-09-04T23:59:14.440 回答
5

是的你可以!(在windows

解决方法很简单,只需将您的虚拟环境移动到任何地方,然后activate.bat在里面进行编辑scripts\

  1. 移动到虚拟环境到想要的目录

  2. 右键单击并编辑activate.bat位于venv_folder\scripts.

  3. 更改VIRTUAL_ENV变量:

     set VIRTUAL_ENV=C:\old_directory\venv_name
    

    进入

     set VIRTUAL_ENV=C:\new_directory\venv_name
    
  4. 保存编辑的批处理文件,就是这样!

注意:我的解决方案应该可以工作并保存windows users设置新的虚拟环境,我怀疑这将在其他操作系统中工作,因为.bat来自MS-DOS

于 2020-11-02T12:13:48.723 回答
5

是的,如果你没有做任何依赖于 virtualenv 的当前目录的事情,这应该是可能的。

但是,如果您可以选择,最好的办法是创建新的 virtualenv 并开始使用新的 virtualenv。这是最安全的选择,并且不太可能在以后引起问题。

该文档确实提到

每个 virtualenv 都有硬编码到其中的路径信息,

例如,如果您已经运行,setvirtualenvproject那么它在您运行后将无法切换到正确的目录,workon ...因此在这种情况下您需要手动修复它。

一般来说,virtualenv 只不过是一个包含必要的 Python 解释器文件和你需要的包的目录。

于 2015-09-04T22:24:20.377 回答
3

使用关于类似主题的这个和其他线程的答案,我制作了一个 bash 脚本,该脚本在 virtualenv 目录本身中定位和执行,将有助于您的 virtualenv 移动。

完成后,每次移动目录时virtualenv --relocatable yourenv都需要更改VIRTUAL_ENV变量,因此如果您不想手动更改它,请使用它。

#!/bin/bash \n 
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
EXISTING=$(grep 'VIRTUAL_ENV=' bin/activate)  
NEWDIR=VIRTUAL_ENV=\"$DIR\"
sed -i -e "s|$EXISTING|$NEWDIR|" bin/activate
source bin/activate

我希望它有所帮助。

于 2019-10-12T16:59:21.643 回答
1

TL;博士

virtualenv-clone包含在virtualenvwrapper中

virtualenv-clone /path/to/old/venv /path/to/new/venv

或者

你也可以试试cpvirtualenv

cpvirtualenv /path/to/old/venv /path/to/new/venv

但是 cpvirtualenv 期望/path/to/old/venv存在于内部$WORKON_HOME,如果不存在则失败。由于 this 调用virtualenv-clone你也可以使用它来代替;避免错误,如

mark@Desktop:~/venvs$ cpvirtualenv ./random/ $WORKON_HOME/random
Copying random as /home/mark/.virtualenvs/venvs/random...
Usage: virtualenv-clone [options] /path/to/existing/venv /path/to/cloned/venv

virtualenv-clone: error: src dir '/home/mark/.virtualenvs/venvs/random' does not exist

根据virtualenvwrapper 文档发出警告

不很好地支持复制虚拟环境。每个 virtualenv 都有硬编码到其中的路径信息,并且可能存在复制代码不知道它需要更新特定文件的情况。谨慎使用。

它实际上是做什么的?根据virtualenv-clone PyPi 页面

用于克隆不可重定位 virtualenv 的脚本。

Virtualenv 提供了一种使 virtualenv 可重定位的方法,然后可以根据需要进行复制。但是,以这种方式使 virtualenv 可重定位会破坏 virtualenv 的无站点包隔离以及可能不受欢迎的相对路径和 /usr/bin/env shebangs 带来的其他方面。

此外,.pth 和 .egg-link 重写似乎没有按预期工作。这试图克服这些问题并提供一种轻松克隆现有虚拟环境的方法。

它执行以下操作:

将 sys.argv[1] 目录复制到 sys.argv[2]

将激活脚本中的硬编码 VI​​RTUAL_ENV 变量更新到新的 repo 位置。(--relocatable 不涉及这个)

如果它们指向旧 Python,则将 bin 中各种脚本的 shebang 更新为新 Python。(保留版本编号。)

它也可以将 /usr/bin/env python shebangs 更改为绝对值,尽管目前尚未公开此功能。

检查克隆的 virtualenv 的 sys.path,如果任何路径来自旧环境,它会在新环境中的 sys.path 中找到任何 .pth 或 .egg 链接文件,并确保更新旧环境的任何绝对路径到新环境。

最后,它再次仔细检查 sys.path,如果仍然存在来自旧环境的路径,则会失败。

注意:此脚本需要 Python 2.7 或 3.4+

于 2021-06-05T12:48:02.600 回答
1

我写了一个venv-move脚本。

第一个参数是 venv 的路径。它会删除__pycache__该路径下的任何内容。

它检测旧路径,并在确认后将其替换为当前路径。即使移动到同一类型的不同机器上,它似乎也可以正常工作。

用 Python 重新编写它是有意义的,但程序会更长。

#!/bin/bash -eu
venv=$1
old=`perl -ne '/VIRTUAL_ENV="(.*?)"/ && print "$1\n"' "$venv/bin/activate"`
new=$PWD/$venv
find "$venv" -name __pycache__ | xargs rm -rf --
files=`fgrep -r "$old" "$venv" -l`
echo "replace $old with $new in:"
echo "$files"
read -p "[yn] ? " YN
[ "$YN" = y ]
sed -i "s:$old:$new:g" $files
于 2021-06-15T03:41:54.580 回答