我可以移动虚拟环境吗?
- 2025-02-21 08:48:00
- admin 原创
- 21
问题描述:
如果我创建一个虚拟环境并将其移动到不同的文件夹,它还能工作吗?
$ 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 中实现,或者我是否只能忍气吞声地克隆它。
我可以就这样不悲伤地mv
生活virtualenv
吗?我确实想避免悲伤。
我查看了在不破坏虚拟环境的情况下重命名虚拟环境文件夹,但这个问题不仅涉及重命名虚拟环境,还涉及将其实际移动到其他目录,包括可能移动到其他用户的目录。这与仅仅重命名虚拟环境不同,尤其是对于不熟悉虚拟环境的人来说。
解决方案 1:
是的。可以将其移动到同一平台上。您可以--relocatable
在现有环境中使用。
从--help
:
--relocatable -- 使现有的虚拟环境可重定位。这将修复脚本并使所有 .pth 文件都具有相关性。
但是,这似乎并没有改变activate
脚本,而只是改变了pip*
和easy_install*
脚本。在activate
脚本中, $VIRTUAL_ENV
环境变量被硬编码为原始的/path/to/original/venv
。$VIRTUAL_ENV
变量也用于设置PATH
活动环境的,因此必须根据新位置进行更改才能调用python
和pip
等,而无需绝对路径。
要修复此问题,您可以更改脚本$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
哇哦,现在您可以安装一些东西并将其加载到新定位的虚拟环境中。
解决方案 2:
适用于 Python 3.3+(带有新的venv
内置模块)
简短回答(无论版本如何):
没有干净、直接的方法来移动虚拟环境
只需重新创建,很简单!!(大多数情况下 - 请参阅评论)
长答案:
从 Python v3.3 开始,该virtualenv
包已成为名为的内置模块venv
。
其他答案中提到的选项--relocatable
尚未包含在内venv
,目前我所知道的没有好的、安全的方法来重命名或重新定位 Python 虚拟环境。
但是,重新创建虚拟环境及其所有当前安装的软件包相当简单。请参阅此答案,或参阅以下部分。在此过程中,您可以在任何位置以任何名称重新创建新环境。
在上面链接的答案中,他提到了一些第三方软件包,它们可能支持直接重命名或移动。如果您决定寻找一种移动虚拟环境的方法,您可以研究一下这些方法是否venv
也适用。
注意:该答案的重点是virtualenv
,而不是venv
。有关如何翻译,请参阅下一节。
注 2:在某些特殊情况下,重新创建虚拟环境可能会更加困难 - 例如离线或需要构建特别大的依赖项等。我在这里不介绍这些例外情况,但请参阅评论以了解一些想法。
venv
与旧的virtualenv
命令语法相比
使用的命令venv
是:
python -m venv
而不仅仅是virtualenv
,它作为原始包中的命令安装。其中“python”指的是您运行 python 可执行文件的方式,可以是多种多样的,例如:
python
py
或py -3.7
类似软件(适用于 Python 3.3+的 Windows Python Launcher并与适用于 Windows 的 Python 捆绑在一起,或者py
可以为 Linux [和 MacOS?] 单独安装的软件包)python3
(适用于同时安装 Python 2 和 Python 3 的 Linux 环境)如果遇到问题,请使用要运行的 python 可执行文件的绝对路径:例如
c:program filespython37python.exe
如果您不确定正在运行哪个版本,您可以随时python --version
找出答案。
如何重建虚拟环境
创建/重新创建虚拟环境很容易,使用一段时间后应该会成为你的第二天性。此过程反映了你在前半部分将脚本作为包(及其依赖项)分发时所做的操作,以及其他人安装你的脚本/包以进行进一步开发时所做的操作。
首先,获取虚拟环境中内容的更新列表。在虚拟环境中,获取其使用的 Python 版本,并将依赖项列表保存到文件中。
使用
python --version
激活的虚拟环境来查看它正在使用的 Python 版本。
* 这是为了清楚起见——你可能因为各种原因想要更新 Python 版本——至少要更新到最新的补丁版本
* 例如,如果现有的 venv 正在使用 Python v3.7.4,但现在 v3.7.6 已经过时 - 请改用 v3.7.6,它应该仅包含非破坏性的安全性和错误修复。
用于
python -m pip freeze > requirements.txt
创建当前软件包依赖项列表并将其放入requirements.txt
文件中。此命令肯定适用于 Linux 或 Git Bash - 不确定是否适用于 Windows 中的 Powershell 或命令行。
现在创建一个新的虚拟环境,然后添加旧虚拟环境的依赖项。
制作新的 venv。
* 确保您使用的是要安装到 venv 的正确版本的 Python。
* 如果你希望它是完全相同的 Python 版本:
+ 在旧的 venv 中,输入“python --version”,然后确保使用该版本的 python 命令创建新的 venv。
* 对于命令中的新 venv 文件夹条目:
+ 添加至所需最终文件夹位置的绝对路径或相对路径。
+ 用于`python -m venv my_new_venv`在新文件夹中的当前工作目录中创建新的虚拟环境`my_new_venv`。
+ venv 文件夹的名称将是 venv 的名称(激活时在提示中显示的内容)。
从文件中安装你的依赖项
requirements.txt
。
* `python -m pip install -r requirements.txt`
您可能需要重新安装处于开发模式的本地包。
请注意,如果您需要查看包安装的具体位置,请使用:
python -m pip list -v
或“详细”选项
-v
将添加有关每个已安装包的一些额外信息,包括其安装路径。这对于确保您保持虚拟、用户和系统安装包的正确性很有用。
此时,您可以删除旧的 venv 文件夹和所有内容。我建议使用 GUI 来实现这一点 - 从 Linux 命令行删除文件通常是永久性的,而且一个小小的拼写错误可能会带来坏消息。
解决方案 3:
但遗憾的是:
不,你不能简单地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
并使用它,否则未经修改?
简短回答:
嗯,你不能。
解决方案 4:
是的,你可以!(在 Windows 中)
解决方法很简单,只需将虚拟环境移动到任何地方,然后activate.bat
在里面编辑scripts
:
将虚拟环境移动到所需目录
右键单击并编辑
activate.bat
位于venv_folderscripts
。将
VIRTUAL_ENV
变量从:
set VIRTUAL_ENV=C:old_directoryenv_name
进入
set VIRTUAL_ENV=C:
ew_directoryenv_name
保存编辑的批处理文件,就完成了!
注意:我的解决方案应该有效,并可让 Windows 用户无需设置新的虚拟环境。我怀疑这在其他操作系统上是否有效,因为.bat
它来自 MS-DOS。
解决方案 5:
该--relocatable
参数virtualenv
似乎允许您这样做。
解决方案 6:
是的,如果您没有做任何依赖于虚拟环境当前目录的事情,这应该是可能的。
但是,如果可以选择,最好的办法是创建新的虚拟环境并开始使用新的虚拟环境。这是最安全的选择,以后出现问题的可能性最小。
文档确实提到:
每个虚拟环境都有硬编码的路径信息,
例如,如果您已经运行setvirtualenvproject
,那么运行后它将无法切换到正确的目录,workon ...
因此在这种情况下您需要手动修复它。
一般来说,虚拟环境只不过是一个包含必要的 Python 解释器文件以及您需要的包的目录。
解决方案 7:
使用这个和其他关于类似主题的帖子的答案,我制作了一个 bash 脚本,该脚本位于virtualenv 目录本身内并在其中执行,将有助于您的 virtualenv 移动。
完成后,每次移动目录时virtualenv --relocatable yourenv
您都需要更改VIRTUAL_ENV
变量,因此如果您不想手动更改它,请使用此方法。
#!/bin/bash
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
我希望它有帮助。
解决方案 8:
我们可以通过创建基础环境的硬链接副本,然后使用此venv_move
脚本更新路径,在虚拟环境之间共享大型模块的存储。
cd /opt
cp -al python3.10-ai python3.10-fastai
venv_move python3.10-fastai
第一个参数是 venv 的路径。它会删除__pycache__
该路径下的所有内容。
它会检测旧路径,并在确认后将其替换为当前路径。然后,它会对激活脚本中的 venv 名称执行类似操作。即使移动到同一类型的另一台机器上,它似乎也能正常工作。
该脚本依赖于bash
GNU sed
,也就是说,它适用于 Linux,而不一定适用于 Mac OS 或 Windows。对于非 Linux 用户来说,用 Python 重写它是有意义的。
#!/bin/bash -eu
venv=${1%/}
find "$venv" -name __pycache__ | xargs rm -rf --
old=`perl -ne '/VIRTUAL_ENV="(.*?)"/ && print "$1
"' "$venv/bin/activate"`
new=$PWD/$venv
old2="(`basename "$old"`)"
new2="(`basename "$venv"`)"
if [ "$old" = "$new" ]; then
echo "venv paths are already set correctly to $new"
else
files=`fgrep -r "$old" "$venv" -l`
echo "$files"
echo "Replace $old with $new in the above files?"
read -p "[yn] ? " YN
if [ "$YN" = y ]; then
sed -i "s:$old:$new:g" $files
fi
files=`fgrep -r "$old2" "$venv"/bin/activate* -l`
echo "$files"
echo "Replace $old2 with $new2 in the above files?"
read -p "[yn] ? " YN
if [ "$YN" = y ]; then
sed -i "s:$old2:$new2:g" $files
fi
fi
解决方案 9:
总结
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
,如果不存在,则会失败。由于这个调用,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-clone PyPi 页面
用于克隆不可重定位虚拟环境的脚本。
Virtualenv 提供了一种使虚拟环境可重定位的方法,然后可以根据需要进行复制。但是,以这种方式使虚拟环境可重定位会破坏虚拟环境的无站点包隔离,以及相对路径和 /usr/bin/env shebang 带来的其他方面,这些方面可能是不受欢迎的。
此外,.pth 和 .egg-link 重写似乎无法按预期工作。这试图克服这些问题并提供一种轻松克隆现有虚拟环境的方法。
它执行以下操作:
将 sys.argv[1] 目录复制到 sys.argv[2]
将激活脚本中的硬编码 VIRTUAL_ENV 变量更新为新的 repo 位置。(--relocatable 不会触及这一点)
如果 bin 中各个脚本的 shebang 指向旧 Python,则将其更新为新 Python。(保留版本号。)
它也可以将 /usr/bin/env python shebangs 更改为绝对的,尽管此功能目前尚未公开。
检查克隆的虚拟环境的 sys.path,如果任何路径来自旧环境,它会在新环境中的 sys.path 中找到任何 .pth 或 .egg 链接文件,并确保将旧环境的任何绝对路径更新到新环境。
最后,它再次检查 sys.path,如果仍然存在来自旧环境的路径,则会失败。
注意:此脚本需要 Python 2.7 或 3.4+
解决方案 10:
在 Ubuntu(以及其他可能的 Linux 变体)上,你可以通过更改 shebangs + 更改 VIRTUAL_ENV 环境变量来移动它。我创建了环境:
python3 -m venv /tmp/whatever
然后在环境中构建了一个大型库/绑定(Mujoco)(即我不想重新创建新的环境)。我意识到我想保存它(/tmp 会在重新启动时被清除)。所以我使用了:
mv /tmp/whatever ~/envs/whatever
此时环境无法工作。您需要:
cd ~/envs/whatever/bin
,使用 识别每个可执行文件ls -F
并查找旁边带有星号的文件。在编辑器中打开每个文件。第一行(称为“shebang”)将以 开头#!
,看起来像#!/tmp/whatever
。将该行更改为#!/home/<user>/envs/whatever
。在同一个“bin”目录中,有“activate”文件,每个文件对应一种 shell。我使用 Bash,所以我编辑
activate
(无扩展名)。查找类似于的行VIRTUAL_ENV="/tmp/whatever"
。最后一次替换路径。
新移动的环境现在应该可以工作了!
解决方案 11:
如上所述,有很多方法可以做到这一点。到目前为止,最好的工具应该是venv-pack。一个命令就可以做到这一点,同时它完成了删除硬编码变量的艰苦工作,VIRTUAL_ENV
因此一旦打包,venv 就可以放入任何地方并且仍然有效。
解决方案 12:
你可以
最近,我们不得不删除服务器上的一些用户,但其中一些用户有遗留代码。我知道这一点,所以我将所有数据移到了某个新目录中。现在是时候使用某些遗留环境运行一些遗留代码了,但不幸的是,它没有起作用。
pip
不起作用,所以我无法获得整洁的冻结requirements.txt
,而且我非常懒得从 一个一个地安装软件包lib/site-packages
。所以我决定寻找一种解决方法。
解决方法bin/activate*
:我更改了文件中的所有旧环境路径bin/pip*
,还替换了bin/python*
链接引用(链接已损坏)。之后它就正常工作了。不确定是否所有更改都是强制性的,但这些信息可能仍然有用。
解决方案 13:
这为我解决了这个问题:
ln -s /path/to/new/venv old-venv-name
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)