重命名 virtualenv 文件夹而不破坏它

Posted

技术标签:

【中文标题】重命名 virtualenv 文件夹而不破坏它【英文标题】:Renaming a virtualenv folder without breaking it 【发布时间】:2011-10-01 11:47:15 【问题描述】:

我已经创建了文件夹并在其中初始化了一个 virtualenv 实例。

$ mkdir myproject
$ cd myproject
$ virtualenv env

当我运行(env)$ pip freeze 时,它会按原样显示已安装的软件包。

现在我想将myproject/ 重命名为project/

$ mv myproject/ project/

但是,现在当我跑步时

$ . env/bin/activate
(env)$ pip freeze

它说 pip 没有安装。如何在不破坏环境的情况下重命名项目文件夹?

【问题讨论】:

这个问题很老,已经有了答案,但我想知道,为什么 OP 不能将 virtualenv 移回原来的位置?显然,这并不能解决移动/重命名的愿望,但这不会恢复正常工作的 virtualenv,还是它已经无可救药地坏了? 是的,你是对的,它会修复虚拟环境,但不能解决问题。 2019 年 11 月,Python3。对我来说最好的解决方案是在aarongorka.com/blog/portable-virtualenv 中描述 【参考方案1】:

如果您使用的是 conda 环境,

conda create --name new_name --clone old_name
conda remove --name old_name --all # or its alias: `conda env remove --name old_name`

【讨论】:

【参考方案2】:

使用 Visual Studio Code (vscode),我刚刚打开了项目根目录中的 ./env 文件夹,并进行了批量查找/替换以切换到我更新的项目名称。这解决了问题。

which python确认

【讨论】:

【参考方案3】:

在你的项目文件夹中运行它:

cd bin
sed -i 's/old_dir_name/new_dir_name/g' *

不要忘记停用和激活。

【讨论】:

效果很好;或者对于 Linux 路径:sed -i "s|$old_dir|$new_dir|g" bin/* sed -i '.original' 's/old_dir_name/new_dir_name/g' * 用于 Mac @Alex 或 sed -i '' 's/old_dir_name/new_dir_name/g' *,如果您不想创建任何备份文件。【参考方案4】:

对我有用的更简单的解决方案:只需将旧虚拟环境的 site-packages 文件夹复制到新环境中即可。

【讨论】:

【参考方案5】:

在带有内置 venv 的 Python 3.3+ 中

从 Python 3.3 开始,virtualenv 包现在作为 venv 模块内置到 Python 中。有一些细微差别,其中之一是 --relocatable 选项已被删除。因此,通常最好重新创建一个虚拟环境而不是尝试移动它。 See this answer 了解有关如何执行此操作的更多信息。

想要移动而不是仅仅重建任何虚拟环境的目的是什么?虚拟环境旨在使用 venv 管理模块/包的依赖关系,以便它可以具有所依赖的给定包或模块的不同和特定版本,并允许在本地安装这些东西的位置。

因此,包应该提供一种从头开始重新创建 venv 的方法。通常这是通过 requirements.txt 文件完成的,有时还使用 requirements-dev.txt 文件,甚至是在包本身的设置/安装中重新创建 venv 的脚本。

可能令人头疼的一个部分是,您可能需要特定版本的 Python 作为可执行文件,如果还没有的话,它很难自动化。但是,在重新创建现有虚拟环境时,可以在创建新环境时简单地从现有 venv 运行 python。之后,通常只需使用 pip 重新安装 requirements.txt 文件中的所有依赖项即可:

来自 Windows 上的 Git Bash:

python -m venv mynewvenv
source myvenv/Scripts/activate
pip install -r requirements.txt

如果您有来自其他本地开发包的多个本地依赖项,它可能会涉及更多,因为您可能需要更新本地绝对路径等 - 尽管如果您将它们设置为适当的 Python 包,您可以从安装一个 git repo,因此可以通过将静态 URL 作为源来避免这个问题。

【讨论】:

【参考方案6】:

我相信“知道为什么”比“知道如何”更重要。因此,这是解决此问题的另一种方法。

当你运行. env/bin/activate时,它实际上执行了以下命令(例如使用/tmp):

VIRTUAL_ENV="/tmp/myproject/env"
export VIRTUAL_ENV

但是,您刚刚将myproject 重命名为project,因此该命令无法执行。 这就是为什么它说pip is not installed,因为您还没有在系统全局环境中安装pip,并且您的virtualenv pip 的来源不正确。

如果你想手动解决这个问题,可以这样:

    用你最喜欢的编辑器,比如 Vim,修改 /tmp/project/env/bin/activate 通常在第 42 行:

    VIRTUAL_ENV='/tmp/myproject/env' => VIRTUAL_ENV='/tmp/project/env'

    在第 1 行修改/tmp/project/env/bin/pip

    #!/tmp/myproject/env/bin/python => #!/tmp/project/env/bin/python

之后,再次激活你的虚拟环境env,你会看到你的pip又回来了。

【讨论】:

如果需要手动更改路径,那么需要注意的是有两个以上的硬编码文件。使用以下内容找到它们:grep -iHnR venv-name /path/to/venv-name | grep -v "^Binary file" | grep -i venv-name。事实上,我注意到在我的一个 Django 实例中,很多包中都有“Python sh-bang 的路径”。 这对我帮助很大。我绝对需要知道为什么...谢谢! 与上面 Keven 的评论相反,我发现编辑这两行可以解决我在移动 virtualenv 方面的所有问题。也许有一些我没有使用的用例,所以不要遇到问题。 从头开始!今天我遇到了一个问题:ipython 在virtualenv 中不起作用。为了解决这个问题,我在ipython 文件中编辑了 bash 标头(它叫什么?),然后它运行良好。 嗯,这对我不起作用,而且我的激活脚本似乎没有第 1 步中提到的第 1 行。有什么变化吗?【参考方案7】:

我总是安装 virtualenvwrapper 来帮忙。在 shell 提示符下:

pip install virtualenvwrapper

virtualenvwrapper 文档中记录了一种方法 - cpvirtualenv 这是你做的。确保您已离开您的环境并返回到 shell 提示符。输入所需的名称:

cpvirtualenv oldenv newenv

然后,如有必要:

rmvirtualenv oldenv

去你的新环境:

workon newenv

【讨论】:

Afrowave 的回答确实应该是公认的方法。 这仅适用于使用virtualenvwrapper,而不仅仅是virtualenv。来自@ryankdwyer 的This answer 更好。 我编辑了我的答案以反映应该安装“virtualenvwrapper”。假设重命名虚拟环境经常发生,我会推荐这种方式。 虽然它依赖于virtualenvwrapper,但它是最简单的。而且效果很好。【参考方案8】:

您需要调整安装以使用相对路径。 virtualenv 提供了 --relocatable 选项。来自the docs:

通常环境与 具体路径。这意味着你 不能移动环境或 将其复制到另一台计算机。你可以 修复环境以实现它 可通过以下命令重定位:

$ virtualenv --relocatable ENV

注意: ENV 是虚拟环境的名称,您必须从 ENV 目录之外运行它。

这将使一些文件 由 setuptools 创建或分发 使用相对路径,并且会改变 所有要使用的脚本 activate_this.py 而不是使用 Python 解释器的位置 选择环境。

注意:你必须在你完成后运行它 将任何软件包安装到 环境。如果你做一个 环境可重定位,然后安装 一个新的包,你必须运行 virtualenv -- 再次可重定位。

【讨论】:

警告:将环境更改为可重定位的不仅仅是让您移动文件夹。 (请参阅从文档中复制的注意:)...它可能有副作用。 --relocatable 选项目前存在许多问题,并且不能保证在所有情况下都有效。该选项可能会在 virtualenv 的未来版本中被弃用。此外,这不会使您的包跨平台。您可以移动目录,但它只能在其他类似的计算机上使用。 @TheDemz grep -EIr '\Wold_venv_name\W' /path/to/new_venv 将帮助找到使用旧 venv 的任何 shabangs,但不是对重新定位的 venv 的完整验证。 另外,您必须编辑 virtualenvwrapper .project 文件,其中包含依赖于 virtualenv 的源代码的路径,假设您使用的是virutalenvwrapper 并且还将项目目录重命名为匹配新的 virtualenv。 我必须先停用 virtualenv,然后才能运行它。【参考方案9】:

另一种对我有用且没有问题的方法是virtualenv-clone:

pip install virtualenv-clone
virtualenv-clone old-dir/env new-dir/env

【讨论】:

这应该被标记为最佳答案。把手放下!克隆需要一些时间,所以请耐心等待。 virtualenv-clone 忽略更新提示。不得不手动进行。除此之外,它很棒。【参考方案10】:

virtualenv --relocatable ENV 不是理想的解决方案。我假设大多数人都希望能够重命名 virtualenv 而没有任何长期的副作用。

所以我创建了一个简单的工具来做到这一点。 virtualenv-mv 的项目页面更详细地概述了它,但基本上你可以使用virtualenv-mv,就像你使用mv 的简单实现一样(没有任何选项)。

例如:

virtualenv-mv myproject project

但是请注意,我刚刚破解了这个。它可能会在不寻常的情况下(例如符号链接的虚拟环境)中断,所以请小心(备份你不能丢失的东西),如果遇到任何问题,请告诉我。

【讨论】:

【参考方案11】:

注意:作为@jb。指出,此解决方案仅适用于轻松(重新)创建的virtualenvs。如果环境需要几个小时才能安装此解决方案,则不建议使用此解决方案


Virtualenvs 很棒,因为它们很容易制作和切换;它们使您不会被锁定在单一配置中。如果您知道项目要求,或者可以得到它们,新建一个virtualenv

创建一个requirements.txt 文件

(env)$ pip freeze > requirements.txt

如果您无法创建requirements.txt 文件,请在删除原始env 之前检查env/lib/pythonX.X/site-packages

删除现有的(env)

deactivate && rm -rf env

创建一个新的virtualenv,激活它并安装要求

virtualenv env && . env/bin/activate && pip install -r requirements.txt


或者,使用 virtualenvwrapper 让事情变得更简单,因为所有 virtualenvs 都保存在一个集中位置

$(old-venv) pip freeze > temp-reqs.txt
$(old-venv) deactivate
$ mkvirtualenv new-venv
$(new-venv) pip install -r temp-reqs.txt
$(new-venv) rmvirtualenv old-venv

【讨论】:

对某些人来说pip install -r requirements.txt 需要几个小时(在树莓派上编译第三方 C 扩展)。 也许是真的,但这对我来说似乎是一个极端情况。我仍然认为这对于许多情况来说可能是一个可行的解决方案。 是的,许多项目(例如 Django 网站)只需要 30 秒即可安装所有内容,即使它们有几十个依赖项(前提是您先下载所有内容并使用 '--no-index --find-links=downloadDir') @bnjmn the one-liner virtualenv env && pip install -r requirements.txt 不会在新环境中安装需求,因为你没有激活它 @Yarin 感谢您指出这一点。我完全错过了它,我自己是virtualenv-wrapper 用户(创建时会自动激活)。我已经更新了我的答案,包括激活 virtualenv 以避免任何混淆。【参考方案12】:

您可以按照以下步骤解决您的问题:

    重命名目录 重新运行:$ virtualenv ..\path\renamed_directory virtualenv 将更正目录关联,同时保留您的软件包 $ scripts/activate $ pip freeze 验证您的包裹是否到位 一个重要的警告,如果您的 virtualenv 目录中的脚本文件中有任何静态路径依赖项,则必须手动更改它们。

【讨论】:

这对我来说是一个非常好的解决方案。由于这个解决方案可能避免了与--relocatable 相关的一些问题,我认为这个解决方案比公认的答案更好。到目前为止,我注意到_new_name_/lib/python2.7 中的许多.pyc 文件仍然引用_old_name_。但是,这似乎不会影响我的环境的工作方式。也许唯一更好的解决方案是使用virtualenvwrapper 或此处的答案中提到的其他一些实用程序。至少这个解决方案不需要安装额外的程序。 像魅力一样工作!

以上是关于重命名 virtualenv 文件夹而不破坏它的主要内容,如果未能解决你的问题,请参考以下文章

Android Studio 重命名而不重构

require.js + cldrjs 为啥重命名配置路径条目会破坏它?

保存文件时没有过早关机的可能性会破坏它

在 PHPStorm 中重命名文件而不重构

如何重命名最后一个字母而不是以python结尾的文件[重复]

如何使用 java 代码重命名和移动文件而不删除内容