【问题标题】:Relative file paths in Python packagesPython 包中的相对文件路径
【发布时间】:2009-06-18 07:51:23
【问题描述】:

如何相对于包的目录引用文件?

我的目录结构是:

/foo 包1/ 资源/ __init__.py 包2/ 资源/ __init__.py 脚本.py

script.py 导入包 package1package2。尽管可以通过系统上的任何其他脚本导入包。我应该如何引用内部的资源,比如package1,以确保在os.path.curdir 是任意的情况下它可以工作?

【问题讨论】:

    标签: python reference packages relative-path


    【解决方案1】:

    如果您想引用foo/package1/resources 文件夹中的文件,您需要使用模块的__file__ 变量。里面foo/package1/__init__.py

    from os import path
    resources_dir = path.join(path.dirname(__file__), 'resources')
    

    【讨论】:

    • 正如另一个答案所指出的,如果您的应用程序打包在一个 zip 文件中,这将不起作用。
    【解决方案2】:

    一种简单/安全的方法是使用来自pkg_resourcesresource_filename 方法(与setuptools 一起分发),如下所示:

    from pkg_resources import resource_filename
    filepath = resource_filename('package1', 'resources/thefile')
    

    或者,如果您在 package1/___init___.py 内部实现此功能:

    from pkg_resources import resource_filename
    filepath = resource_filename(__name__, 'resources/thefile')
    

    这为您提供了一个干净的解决方案,而且(如果我没记错的话)zip 安全。

    【讨论】:

      【解决方案3】:

      如果您使用 twisted.python.modules,您可以在使用 zip 安全的同时使用非常方便的 API。

      例如,如果我有一个data.txt,其中包含一些文本,而这个sample.py 在一个目录中:

      from twisted.python.modules import getModule
      moduleDirectory = getModule(__name__).filePath.parent()
      print repr(moduleDirectory.child("data.txt").open().read())
      

      然后导入sample 会这样做:

      >>> import sample
      'Hello, data!\n'
      >>>
      

      如果您的模块位于常规目录中,getModule(__name__).filePath 将是 FilePath;如果它在一个 zip 文件中,它将是一个ZipPath,它支持大多数但不是所有的相同 API。

      【讨论】:

        【解决方案4】:

        这是个坏主意,因为如果你的包是作为 zipped egg 安装的,那么资源可能不可用。

        如果您使用 setuptool,请不要忘记将 zip_safe=False 添加到 setup.py 配置中。

        【讨论】:

        • 这是真的,但它确实应该出现在评论而不是答案中,因为它没有回答问题。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-11-20
        • 1970-01-01
        • 2011-12-08
        • 2014-11-15
        • 1970-01-01
        • 1970-01-01
        • 2014-04-24
        相关资源
        最近更新 更多