我可以把一个虚拟的东西变成一个鸡蛋

问题描述 投票:1回答:2

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

python virtualenv egg
2个回答
1
投票

我特别需要将任意数量的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文件中,但您确实需要元数据

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

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

top_level.txt包含你的virtualenv中的所有顶级包名,每行一个,即如果你已经安装了命名空间包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中的命名空间打包应该按原样运行。

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

更正:你不能以这种方式做入口点,不管没有任何严重的黑客攻击。分发名称(在本例中为spaghetti)将用于所有入口点而不是包名称。没有直接的方法来规避这一点。


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


0
投票

出于几个原因,你不应该这样做

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

此外,蟒蛇蛋有点出路。如果要创建二进制分发,则应使用较新的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
© www.soinside.com 2019 - 2024. All rights reserved.