重命名 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 的未来版本中被弃用。此外,这不会使您的包跨平台。您可以移动目录,但它只能在其他类似的计算机上使用。 @TheDemzgrep -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。指出,此解决方案仅适用于轻松(重新)创建的virtualenv
s。如果环境需要几个小时才能安装此解决方案,则不建议使用此解决方案
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 文件夹而不破坏它的主要内容,如果未能解决你的问题,请参考以下文章
require.js + cldrjs 为啥重命名配置路径条目会破坏它?