我可以把 virtualenv 做成鸡蛋吗

can I make a virtualenv into an egg

我可以使用设置工具制作一个 python 鸡蛋:python setup.py bdist_egg。理论上,我应该能够为每个带有 setup.py 文件的安装包执行此操作。是否可以将整个 virtualenv 虚拟 python 环境封装到一个 python egg 中?

你不应该这样做有几个原因

即使您能够做到这一点,它也不会像您期望的那样工作。如果用户已经在你的 egg 中安装了其中一个包,它们就会发生冲突,因为 python egg 不会添加额外的命名空间。

此外,python 鸡蛋也快出来了。如果你想创建一个二进制发行版,你应该使用更新的 python wheels.

如果您的项目有依赖项,只需在 setup.py 中声明这些依赖项,pip 就会安装它们。如果您有一些 PyPi 上不存在的依赖项,或者您需要一个非常特定的旧版本的包,只需将这些包作为子包包含在您的包中。

/my_package
    __init__.py
    /libs
        __init__.py
        /non_pypi_package
        /legacy_package 

然后在您的代码中,而不是将它们导入为

import non_pypy_package

你会用

from my_package.libs import non_pypi_package

我特别需要将任意数量的Python包打包成一个.egg,因为我使用的系统只接受 个鸡蛋,每个鸡蛋都需要单独列出,当所需软件包的数量发生变化时,这变得非常笨重。

一个 .egg 文件只是一个 .zip 和一个名为 EGG-INFO 的元数据文件夹,并且 名称中的版本号。您基本上可以 cd lib/python-x.y/site-packages,然后 zip -r spaghetti-0.0.1.egg 将内容压缩到 spaghetti-0.0.1.egg 文件中,但您确实需要元数据

如果你很幸运并且你没有使用入口点或其他此类高级功能的包,你可以在 site-packages 中创建一个名为 EGG-INFO 的目录,其中包含以下文件:

dependency_links.txt
entry_points.txt
not-zip-safe
PKG-INFO
requires.txt
top_level.txt

PKG-INFO外全部包含以下内容

Metadata-Version: 1.1
Name: spaghetti
Version: 0.0.1

and top_level.txt 包含来自你的 virtualenv 的 all 顶级包名,每行一个,即如果你安装了命名空间包 zope.componentsqlalchemy,你的 top_level.txt 应该有

zope
sqlalchemy

当然事情并不总是这么简单。对于 Python 2.7 上的命名空间包(zope.component 就是这种情况),有一些神奇的 .pth 条目。对于这些,您需要在包中创建空的 __init__.pys,或者将它们列在 EGG-INFO/namespace_packages.txt;在 zope.component 的情况下,zope 是一个没有 __init__.py 的命名空间包,因此 EGG-INFO 应该有一行 namespace_packages.txtzope .然而,Python 3 中的命名空间打包应该可以在没有这个中间步骤的情况下按原样工作。

同样,如果您需要使用入口点,则需要将所有包的鸡蛋信息中的 entrypoints.txt 连接到鸡蛋的 entrypoints.txt 中。

更正:你不能以这种方式做入口点,无论如何都不是没有任何严重的黑客攻击。分发名称,在本例中为 spaghetti,将用于所有入口点而不是包名称。没有直接的方法可以避免这种情况。


最后,wheel 确实可以被认为是一种优于 egg 的格式,但它们不兼容,如果你 可以 你应该使用wheel 用于打包虚拟环境。但是如果一个系统特别希望有一个旧的 .egg 文件格式的文件,它就不能与 wheel 一起工作。此外,.egg有时不需要安装,它可以从PYTHON_PATH按原样使用...