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

时间:2011-07-08 18:02:15

标签: python ubuntu virtualenv pip

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

$ mkdir myproject
$ cd myproject
$ virtualenv env

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

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

$ mv myproject/ project/

然而,现在我跑的时候

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

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

12 个答案:

答案 0 :(得分:140)

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

  

通常环境与a有关   具体路径。那意味着你   不能移动周围的环境或   将其复制到另一台计算机。您可以   修复一个环境来实现它   可以使用命令重新定位:

     

$ virtualenv - 可定位的ENV

     

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

     

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

     

注意:您必须在此之后运行此操作   安装任何包进入   环境。如果你做了   环境可重定位,然后安装   一个新包,你必须运行virtualenv    - 再次可以回复。

答案 1 :(得分:100)

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

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

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

但是,您刚刚将myproject重命名为project,因此该命令无法执行。 这就是原因pip is not installed,因为您尚未在系统全局环境中安装pip,并且您的virtualenv pip未正确采购。

如果您想手动修复此问题,可以采取以下方式:

  1. 使用您喜欢的编辑器如Vim,通常在第42行修改/tmp/project/env/bin/activate

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

  2. 修改第1行中的/tmp/project/env/bin/pip

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

  3. 之后,再次激活您的虚拟环境env,您会看到pip再次回来。

答案 2 :(得分:35)

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


Virtualenvs很棒,因为它们易于制作和转换;它们使您无法锁定单一配置。如果您了解项目要求,或者可以获得项目要求,制作新的virtualenv

  • 创建requirements.txt文件

    (env)$ pip freeze > requirements.txt

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

    deactivate && rm -rf env

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

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


或者,使用virtualenvwrapper使事情变得更容易,因为所有的virtualenv都保存在一个集中的位置

$(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

答案 3 :(得分:28)

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

pip install virtualenvwrapper

virtualenvwrapper文档中记录了一种方法 - cpvirtualenv 这是你做的。确保您不在环境中并返回shell提示符。使用所需名称键入:

cpvirtualenv oldenv newenv

然后,如有必要:

rmvirtualenv oldenv

转到你的新人:

workon newenv

答案 4 :(得分:14)

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

  1. 重命名您的目录
  2. 重播:$ virtualenv ..\path\renamed_directory
  3. virtualenv将在保留包裹的同时更正目录关联
  4. $ scripts/activate
  5. $ pip freeze验证您的包已到位
  6. 一个重要的警告,如果virtualenv目录中的脚本文件中存在任何静态路径依赖关系,则必须手动更改这些依赖关系。

答案 5 :(得分:10)

另一种方法可以帮助我很多次没有问题,virtualenv-clone

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

答案 6 :(得分:4)

(项目文件夹内)

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

不要忘记停用并激活

答案 7 :(得分:1)

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

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

例如:

virtualenv-mv myproject project

但请注意,我刚刚将其搞砸了。它可能会在不寻常的情况下破裂(例如符号化的virtualenvs)所以请小心(备份你能承受的损失)并告诉我你是否遇到任何问题。

答案 8 :(得分:0)

在具有内置venv的Python 3.3+中

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

想要移动而不只是重新创建任何虚拟环境的目的是什么?虚拟环境旨在通过venv管理模块/软件包的依赖关系,以便它可以具有其依赖的给定软件包或模块的不同版本和特定版本,并允许将这些内容放置在本地。 / p>

因此,程序包应提供一种从头开始重新创建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作为来源来避免此问题。

答案 9 :(得分:0)

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

答案 10 :(得分:0)

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

which python确认

答案 11 :(得分:0)

如果您使用的是conda env,

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