【问题标题】:Accessing files in python egg from inside the egg从 egg 内部访问 python egg 中的文件
【发布时间】:2012-09-25 23:54:13
【问题描述】:

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

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 对象获取信息,但我无法从文档中了解我应该如何指定我的分发名称?它找不到它。

所以,我正在寻找有关使用 pkg_resources.get_distribution 的正确解决方案,而且如果最终有一个完整的解决方案可以从 egg 中读取任何文件,那就太好了。

谢谢!

【问题讨论】:

    标签: python pkg-resources


    【解决方案1】:

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

    __loader__.get_data('path/within/the/egg')
    

    【讨论】:

    • 这里的用法我不清楚,能否请您详细说明并提供更完整的示例?另外,艾伦似乎有一个很好的鸡蛋不一定是拉链
    • 是的,这是真的,这不是真正的访问 Eggs 中的文件,而是从压缩的 Eggs 中访问文件,它们实际上只是你可以放入 pythonpath 的压缩文件。这与 setuptools/pkg_resources 无关,后者只是提供了一种处理鸡蛋的不同方式,但并非必须这样做。
    【解决方案2】:

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

    eggs 只是将一堆 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。如果您正在构建一个打包工具,您应该知道把手放在哪里,仅此而已。

    【讨论】:

    • 像“restez==0.3.2”这样的名字的组成规则是什么?如果我有一个鸡蛋 my_program_0.9.egg 我应该说“my_program==0.9”吗?如果文件名中没有版本号怎么办?
    • @EugeneSajine packages.python.org/distribute/…。版本号不在文件名中,它在分发元数据中 - 您在 setup.py 中指定的内容。
    • 您是说这样感兴趣的文件不必在包内吗?因为我的问题中的 p2 暗示了接近的方法,但正是这种限制。抱歉,我现在无法自行检查
    • @EugeneSajine 如果您想访问 PKG-INFO 数据,请使用 pkginfo 库。我认为你对鸡蛋的实现细节做了太多假设——他们的系统被设计得比我对程序员说的更透明,你应该不需要需要知道一个发行版是否在一个压缩的鸡蛋,未压缩的鸡蛋,或通过 bdist 手动安装;鸡蛋只是将这些文件一起传递的一种方式,但程序员不应该准确地知道他正在使用的库是如何安装的 - 这可能随时更改。
    • 很好的解释。但是,如果您使用的是需要资源完整路径的依赖库,则它实际上不起作用。在这种情况下,你唯一能做的就是使用resource_filename,如果鸡蛋被压缩,它就不起作用
    猜你喜欢
    • 2018-09-21
    • 1970-01-01
    • 2011-04-08
    • 2011-03-05
    • 2011-12-29
    • 2011-02-07
    • 2010-09-15
    • 1970-01-01
    • 2016-05-13
    相关资源
    最近更新 更多