将完整的Virtualenv复制到另一台电脑

35

我有一个位于/home/user/virtualenvs/Environmentvirtualenv。现在我需要在另一台电脑上使用这个环境。所以我安装了virtualenv-clone并使用它来克隆/Environment。然后通过USB将其复制到另一台电脑上。我可以使用source activate来激活它,但是当我尝试使用sudo ./Environment/bin/python启动python解释器时,我得到以下错误:

./bin/python: 1: ./bin/python: Syntax Error: "(" unexpected

如果没有使用sudo执行它,会出现二进制格式的错误。但这怎么可能呢?我只是复制了它。或者有更好的方法吗?我不能只用pip freeze,因为在/Environment/lib/python2.7/site-packages/中有一些我自己编写的包需要复制。据我所知,pip freeze只是创建一个包列表,然后由pip下载和安装。


这些包最初是如何进入site-packages的呢?你一定安装了它们,并且它们肯定存在于版本控制中。 - Daniel Roseman
我创建了一个文件夹,添加了一个__init__.py文件,并将我的模块放在其中,这样我就可以从使用虚拟环境的项目中访问它们。 - vicco
你不应该这样做。你打算如何部署这些库?你需要将它们放在可以在线安装的地方,并且你需要打包它们,以便可以通过pip进行安装。或者,如果它们只是你项目的一部分,它们应该在你的项目内部。 - Daniel Roseman
好的,知道了。它们不仅仅是项目的一部分,实际上它们是我为我的项目编写的库。我认为我应该将它们存储在那里,这样我就可以轻松地访问它们。所以我应该把它放到一个真正的包中,添加一个 setup.py,然后我就可以简单地将它们安装到另一台计算机上的虚拟环境中了? - vicco
5个回答

38

在源计算机上执行以下步骤:

  1. workon [environment_name](激活虚拟环境)
  2. pip freeze > requirements.txt(将依赖包保存到requirements.txt文件中)
  3. 将requirements.txt文件复制到其他PC上

在另一台PC上:

  1. 使用mkvirtualenv [environment_name]创建虚拟环境
  2. workon [environment_name](激活虚拟环境)
  3. pip install -r requirements.txt(安装requirements.txt中指定的所有依赖包)

完成上述步骤后,你就可以开始使用程序了。

其他资源:


这是否也会复制我自己编写的site-packages中的包? - vicco
它将在目标机器上创建一个工作环境的副本。它将自行下载所需的所有内容。 - Anuj Gupta
我不太明白它如何从文本文件中重新创建我自己编写的软件包?requirements.txt 文件只包含可供下载的软件包。 - vicco
1
@vicco,不行的,因为freeze只会打印出通过pip安装的软件包,即使它打印出了你的软件包,如果它不在pip上,另一台电脑显然无法从pip下载它。你可能需要手动复制这些软件包。 - dietbacon
1
如果要求使用本地存储库,则此方法无效。 - Alexander McFarlane
在目标机器上,可以使用需求文件直接运行mkvirtualenv,例如:mkvirtualenv -r requirements_file ENVNAME。 - Kurumi Tokisaki

14

无法使用pip freeze?

场景:你的当前系统上安装了一些非常难以使用 pip freeze 进行迁移的库,就算手动下载和安装wheel(例如gdal、fiona、rasterio)仍然会导致项目崩溃,可能是安装顺序错误或依赖关系错误等原因。

这就是我加入一个项目时遇到的情况。

对于这种情况,当你最终得到正确的环境时,你基本上不想在将项目移植到新的机器时再次经历相同的痛苦。我多次做了这样的尝试,直到最终找到解决方法。

免责声明:

在我继续之前,先声明一下:

我不认为这是最好的方法,但在此情况下它是最好的。

我也无法保证这种方法可以在不同的操作系统之间切换时起作用,因为我只在 Windows 机器之间尝试过。实际上,由于Unix型操作系统中虚拟环境文件夹的结构与Windows不同,我不希望这种方法在从Windows切换到其他操作系统时能够生效。

最后,用Docker处理所有这些可能是最好的方法。我的计划是最终这样做。我以前从未为非Web应用程序项目使用过Docker,而我需要一个快速解决方案,因为我的电脑坏了,无法延迟该项目。在将Docker应用于该项目后,我会更新此线程。

窍门

那么这就是我所做的:

  • 在新机器上安装相同版本的Python。如果旧版本使用的是3.9,则在新机器上安装3.9。记下其可执行文件所在的位置,通常类似于C:\Users\User\Appdata\Local\Programs\Python\PythonXX。

  • 压缩虚拟环境文件夹,将其复制到项目目录中,然后在新机器上解压所有文件。

  • 使用您选择的文本编辑器或更好的IDE,使用“所有文件中搜索”的功能查找对旧路径的所有引用:C:\Users* your-old-username *。

  • 将它们替换为新的引用。对于我的情况,我必须在虚拟环境文件夹中的以下文件中执行此操作:pyvenv.cfg、Scripts/activate、Scripts/activate.bat、Scripts/activate.fish 和 Scripts/activate.nu。

就是这样了!

祝大家好运。


1
不确定为什么这个还没有被点赞,这正是我想要做的! - Spencer

2

我认为所发生的情况就是您仅仅将源文件中的符号链接作为二进制文件复制到目标机器上。您应该使用rsync -l命令进行复制,以保留这些链接。


1

我分享我的经验。

Suppose another PC does not install Python
Python version: 3.7.3 
Platform: Platform: Windows 10, 7 (64bit)

以下对我有效。
步骤:
1.下载Windows嵌入式压缩文件
2.下载get-pip.py(因为嵌入式压缩文件不提供pip)。
3.[可选]安装tkinter,请参阅本文:Python嵌入式压缩包:安装Tkinter
4.选择打包方法(我使用NSIS:https://nsis.sourceforge.io/Download)。
文件夹图片:
- main.nsi
- InstallData
    - contains: Step1 & Step2
- YourSitePackages  # I mean that packages you do not intend to publish to PyPI.
    - LICENSE
    - MANIFEST.in
    - README.rst
    - ...
    - requirements.txt
    - setup.py

关于main.nsi的简要内容如下:

!define InstallDirPath "$PROGRAMFILES\ENV_PYTHON37_X64"
!define EnvScriptsPath "${InstallDirPath}\Scripts"
...

CreateDirectory "${InstallDirPath}"  # Make sure the directory exists before the writing of Uninstaller. Otherwise, it may not write correctly!
SetOutPath "${InstallDirPath}"
SetOverwrite on
File /nonfatal /r "InstallData\*.*"

SetOutPath "${InstallDirPath}\temp"
SetOverwrite on
File /nonfatal /r "YourSitePackages\*.*"
nsExec::ExecToStack '"${InstallDirPath}\python.exe" "${InstallDirPath}\get-pip.py"'  # install pip
nsExec::ExecToStack '"${InstallDirPath}\Scripts\pip.exe" install "${InstallDirPath}\temp\."'  # install you library. same as: `pip install .`
RMDir /r "${InstallDirPath}\temp"  # remove source folder.
...

/*
Push ${EnvScriptsPath}  # Be Careful about the length of the HKLM.Path. it is recommended to write it to the HKCU.Path, it is difficult for the user path to exceed the length limit
Call AddToPath  # https://nsis.sourceforge.io/Path_Manipulation
*/


希望有人从中受益。

1
通常我使用virtualenv创建一个新的环境,然后进入我想要复制的环境,将所有文件夹复制并粘贴到我刚创建的环境文件夹中,但最重要的是在询问是否要替换目标文件时,选择跳过这些文件。这样可以保留你的设置。 至少对我来说,这种方法非常有效。 希望对你也有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接