我能移动虚拟世界吗?

这个问题不是重复的。

它不仅适用于 重新命名虚拟环境,而且实际上适用于 移动不同的目录,可能包括不同用户的目录。

这与仅仅重命名一个虚拟环境是不一样的,特别是对于不熟悉 Virtual alenvs 的人来说。

如果我创建一个 Virtual alenv,并将其移动到另一个文件夹,它还能工作吗?

$ 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

我的意思是,这与其说是一个关于尝试这种方法是否明智的问题(当然,除非这种智慧是幽默的) ,倒不如说是关于这种方法是否可行的问题。我真的很想知道是否可以在 Python3中实现,或者只需要复制 忍着吧就可以了。

我可以只是 mv一个 virtualenv这样没有悲伤? 我想避免悲伤。

111452 次浏览

是的,如果你没有做任何依赖于虚拟工作目录的事情,这应该是可能的。

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

文档 确实提到过:

每个 Virtual alenv 都有硬编码的路径信息,

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

通常,viralenv 只不过是一个目录,其中包含必要的 Python 解释器文件和所需的包。

但是,唉:

不,不能简单地使用 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和使用它,否则未经修改?

简短的回答:

I'll let Boromir say it, so he can make it clear:

好吧,你 不行

virtualenv--relocatable参数似乎允许您这样做。

是的。在同一个平台上移动它是可能的。你可以在现有的环境下使用 --relocatable

来自 --help:

——可重定位——使一个现有的 viralenv 环境可重定位。 这将修复脚本并使所有.pth 文件相对。

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

要解决这个问题,你可以改变 activate脚本中的 $VIRTUAL_ENV环境变量(例如使用 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

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

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

执行 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

希望能有所帮助。

对于 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或类似的软件包(用于 Windows 的 Python 启动程序 for Python 3.3 + ,与 Python for Windows 捆绑在一起,或者 py软件包,可以单独安装于 Linux [和 MacOS? ])
  3. python3(用于双重安装 python2和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,这应该只包括非破坏性安全性和 bug 修复。
  2. 使用 python -m pip freeze > requirements.txt创建当前包依赖项的列表,并将它们放入 requirements.txt文件中。这个命令肯定可以在 Linux 或 Git Bash 中工作——但不能100% 肯定 Powershell 或 Windows 中的命令行。

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

  1. 做你的新货吧。

    • 确保您使用的是您想要安装到 venv 的正确的 python 版本。
    • 如果你想要的是完全相同的 Python 版本:
      • 在旧的 venv 中,键入“ python —— version”,然后确保使用该版本的 python 命令创建新的 venv。
    • 对于命令中新的 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 命令行永久性的,一个小的输入错误可能是坏消息。

是的,你可以! (在 windows中)

变通方法很简单,只需将虚拟环境移动到任何地方,然后在 scripts\中编辑 activate.bat:

  1. 移动到虚拟环境中所需的目录

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

  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

DR

virtualenv-clone 是包含在 < a href = “ https://pypi.org/project/viralenvwrapper/”rel = “ nofollow norefrer”> viralenvwrapper 中的一部分

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

或者

你也可以试试 cpvirtualenv

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

但是 cpviralenv 希望 /path/to/old/venv存在于 $WORKON_HOME内部,如果它不存在,就会失败。因为这个函数调用 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

根据 Viralenvwrapper 文档发出警告

不支持复制虚拟环境 有硬编码的路径信息,并可能有情况下 复制代码不知道它需要更新特定的文件。使用 小心点。

它到底是做什么的? 根据 < a href = “ https://PyPi.org/project/viralenv-clone/”rel = “ nofollow noReferrer”> viralenv-clone PyPi 页面

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

Virtualenv 提供了一种可重定位的方法 然后复制我们想要的。然而,使虚拟可重定位 这样就打破了 viralenv 的无站点包隔离 以及相对路径和/usr/bin/env 附带的其他方面 可能是不受欢迎的。

而且,. pth 和. egg-link 重写似乎不起作用 试图克服这些问题,并提供一种方法 很容易地克隆一个现有的 Virtual。

它执行以下任务:

将 sys.argv [1] dir 复制到 sys.argv [2]

将激活脚本中的硬编码 VIRTUAL _ ENV 变量更新为 新的回购位置

将 bin 中各种脚本的 shebang 更新到新的 Python 如果他们指向旧的 Python (版本号保留)

它也可以将/usr/bin/env python shebang 更改为绝对值, 虽然这个功能目前还没有公开。

检查克隆的 viralenv 的 sys.path 以及是否有任何路径是 从旧环境中找到任何. pth 或. egg 链接文件 位于新环境中的 sys.path,并确保任何绝对 到旧环境的路径被更新到新环境。

最后,它再次检查 sys.path,如果有,则会失败 从现在的旧环境静止的路径。

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

我写了一个 让开脚本。

第一个参数是 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