在python中访问资源文件的方法

时间:2012-06-07 15:38:45

标签: python

在python程序中访问资源的正确方法是什么。

基本上在我的许多python模块中,我最终都编写了这样的代码:

  DIRNAME = os.path.split(__file__)[0]

  (...) 

  template_file = os.path.join(DIRNAME, "template.foo")

哪个好,但是:

  • 如果我将开始使用python zip包
  • ,它将会中断
  • 是样板代码

在Java中,我有一个完全相同的函数 - 但是当代码位于一堆文件夹中时以及它被打包在.jar文件中时都有效。

Python中是否有这样的功能,或者我可能使用其他任何模式。

3 个答案:

答案 0 :(得分:16)

您需要查看stdlib中的get_data或setuptools / distribute中的pkg_resources。您使用哪一个可能取决于您是否已经使用分发将您的代码打包为鸡蛋。

答案 1 :(得分:2)

试图了解我们如何将两个方面结合起来

  1. 加载本机文件系统中的资源
  2. 以压缩文件打包
  3. 阅读zipimport快速教程:http://www.doughellmann.com/PyMOTW/zipimport/

    我看到以下示例:

    import sys
    sys.path.insert(0, 'zipimport_example.zip')
    import os
    import zipimport
    importer = zipimport.zipimporter('zipimport_example.zip')
    module = importer.load_module('example_package')
    print module.__file__
    print module.__loader__.get_data('example_package/README.txt')
    

    我认为__file__的输出是“zipimport_example.zip/example_package/__init__.pyc”

    需要从内部检查它的外观。

    但是我们总能做到这样的事情:

    if ".zip" in example_package.__file__:
        ... 
        load using get_data
    else:
        load by building the correct file path
    

    [编辑:]我试图更好地解决这个问题。

    如果包被导入为压缩文件,则会发生两件事

    1. __ file__在其路径中包含“.zip”。
    2. __ loader__在名称空间
    3. 中可用

      如果满足这两个条件,那么你可以在包中做到:

      print __loader__.get_data(os.path.join('package_name','README.txt'))
      

      否则模块已正常加载,您可以按照常规方法加载文件。

答案 2 :(得分:0)

我想zipimport标准的python模块可能是一个答案......

编辑:好吧,不是直接使用模块,但是如示例中所示使用sys.path可能是一个好方法:

  • 我有一个zip文件test.zip,其中包含一个python模块test和一个文件test.foo
  • 测试压缩的python模块test是否可以知道test.foo,它包含以下代码:

c

import os
DIRNAME = os.path.dirname(__file__)
if os.path.exists(os.path.join(DIRNAME, 'test.foo')):
    print 'OK'
else:
    print 'KO'

测试看起来不错:

>>> import sys
>>> sys.path.insert(0, r'D:\DATA\FP12210\My Documents\Outils\SVN\05_impl\2_tools\test.zip')
>>> import test
OK
>>> 

因此,解决方案可能是在您的zip文件中循环以检索所有python模块,并将其添加到sys.path;理想情况下,这段代码将是您的应用程序加载的第一个代码。