我特别需要将任意数量的 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.component 和sqlalchemy,你的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.txt 一行zope。然而,Python 3 中的命名空间打包应该可以在没有这个中间步骤的情况下按原样工作。
同样,如果你需要使用入口点,你需要将所有包的 egg 信息中的 entrypoints.txt 连接到你 egg 的 entrypoints.txt 中。
更正:你不能以这种方式做入口点,无论如何也不能没有任何严重的黑客攻击。分发名称(在本例中为 spaghetti)将用于所有入口点,而不是包名称。没有直接的方法可以规避这一点。
最后,wheel 确实可以被认为是优于egg 的格式,但它们不兼容,如果您可以您应该使用wheel 来打包虚拟环境。但是,如果一个系统特别希望有一个旧的.egg 文件格式的文件,它就不能使用wheel。此外,.egg 有时不需要安装,它可以从PYTHON_PATH 直接使用...