从蛋内部访问python egg中的文件

时间:2012-10-04 21:00:33

标签: python pkg-resources

问题是试图获得如何做到这一点的确切指示。之前几乎没有尝试过,这似乎不是完整的解决方案:

solution to move the file inside the package

solution to read as zip

accessing meta info via get_distribution

手头的任务是阅读有关程序运行的蛋的信息。 我理解的方法很少:

  1. 对鸡蛋的位置进行硬编码并将其视为zip存档 - 会起作用,但不够灵活,因为如果将文件移动到其他位置,则需要对其进行编辑和重新编译

  2. 使用ResourceManager().resource_filename(__name__, filename) - 这似乎是有限的,因为我无法访问鸡蛋内部的文件,但不能访问包内。文件名中的“../../EGG-INFO/PKG-INFO”等符号不起作用,给出KeyError。所以也不好。

  3. 使用dist = pkg_resources.get_distribution("dist_name")然后使用dist对象获取信息,但我无法从文档中了解如何指定我的分发名称?它找不到它。

  4. 所以,我正在寻找关于使用pkg_resources.get_distribution的正确解决方案,最好有一个完整的解决方案来从鸡蛋内部读取任何文件。

    谢谢!

2 个答案:

答案 0 :(得分:8)

Setuptools / distribute / pkg_resources旨在成为标准Python distutils的一种透明覆盖,这种覆盖非常有限,并且不允许以良好的方式分发代码。

鸡蛋只是将一堆python文件,数据文件和元数据放在一起的一种方式,有点类似于Java JAR - 但是python包可以从源代码安装,即使没有en egg(这是一个不存在的概念)在标准分发中。)

所以这里有两个场景:你是一个试图在库中使用某个文件的程序员,在这种情况下,为了从你的发行版中读取任何文件,你不需要它的完整路径 - 你只需要一个带有内容的打开文件对象,对吧?所以你应该做这样的事情:

from pkg_resources import resource_stream, Requirement
resource_stream(Requirement.parse("restez==0.3.2"), "restez/httpconn.py")

这将返回您从软件包分发中请求的文件的打开的可读文件。如果它是一个拉链蛋,它将被自动提取。

请注意,您应该在(restez)中指定包名称,因为分发名称可能与包不同(例如,分发Twisted然后使用扭曲的包名称)。需求解析使用以下语法:http://setuptools.readthedocs.io/en/latest/pkg_resources.html#requirements-parsing

这应该足够了 - 一旦你知道如何从蛋中取出文件,你就不需要知道蛋的路径了。

如果您真的想要完整路径,并且确定您的鸡蛋未压缩,请使用resource_filename而不是resource_stream。

否则,如果您正在构建一个“包装工具”并且需要访问包装的内容,无论是鸡蛋还是其他任何东西,您都必须亲自手动完成,就像pkg_resources那样{{3 }。 “查询鸡蛋内容”没有精确的API,因为没有用例。如果你是一个只使用库的程序员,请像我建议的那样使用pkg_resources。如果你正在构建一个包装工具,你应该知道把手放在哪里,就是这样。

答案 1 :(得分:3)

可以使用模块上的zipimporter属性访问用于加载模块的__loader__,因此访问egg中的文件应该非常简单:

__loader__.get_data('path/within/the/egg')
相关问题