10

问题是试图获得有关如何执行此操作的确切说明。之前的尝试很少,似乎不是完整的解决方案:

将文件移动到包内的解决方案

以 zip 格式读取的解决方案

通过 get_distribution 访问元信息

手头的任务是读取有关运行程序的鸡蛋的信息。据我了解,有几种方法:

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

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

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

所以,我正在寻找关于使用pkg_resources.get_distributionplus 的正确解决方案,如果最终有一个完整的解决方案可以从鸡蛋内部读取任何文件,那就太好了。

谢谢!

4

2 回答 2

8

Setuptools/distribute/pkg_resources 被设计成一种对标准 Python distutils 的透明覆盖,它非常有限,不允许以一种好的方式分发代码。

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

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

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

这应该足够了——一旦你知道如何从 egg 内部获取文件,你就不需要知道 egg 的路径。

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

否则,如果您正在构建“打包工具”并且需要访问包的内容,无论是鸡蛋还是其他任何东西,您都必须自己手动完成,就像 pkg_resources 所做的(pkg_resources source)一样。没有用于“查询鸡蛋内容”的精确 API,因为没有用例。如果您是只使用库的程序员,请按照我的建议使用 pkg_resources。如果你正在构建一个打包工具,你应该知道把手放在哪里,仅此而已。

于 2012-10-29T17:08:31.233 回答
3

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

__loader__.get_data('path/within/the/egg')
于 2012-10-26T19:06:04.850 回答