31

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

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

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

  (...) 

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

这没关系,但是:

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

在 Java 中,我有一个功能完全相同 --- 但在代码位于一堆文件夹中和打包在.jar文件中时都可以工作。

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

4

3 回答 3

20

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

于 2012-06-07T16:11:51.407 回答
2

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

  1. 在本机文件系统中加载资源
  2. 打包成压缩文件

阅读有关 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__ 在名称空间中可用

如果满足这两个条件,那么您可以在包中执行以下操作:

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

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

于 2012-06-07T15:57:17.327 回答
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; 理想情况下,这段代码是您的应用程序加载的第一个代码。

于 2012-06-07T15:48:25.333 回答