从python egg访问文件

时间:2018-04-11 18:27:29

标签: python egg

您好我正在使用python包装。我有3个non-code个文件,即['synonyms.csv', 'acronyms.csv', 'words.txt']

  • 这些文件存在于文件夹结构Wordproject/WordProject/Repository/DataBank/
  • 我在路径RepositoryReader
  • 上有一个Wordproject/WordProject/Repository/课程
  • 我编写了一个代码,用于提取RepositoryReader的当前位置,然后查找名为subdirectory的{​​{1}}并在那里查找3个文件。

问题是当我从代码中创建DataBank然后运行它时,

我的代码给了我错误:

  

无法在X:\ 1找到该文件。项目\的Python \ Wordproject \ VENV \ lib中\站点包\ Wordproject-1.0-py3.6.egg \ Wordproject \库\数据库\ synonyms.csv

如果路径是鸡蛋,则无法获取文件或从路径中读取文件。它有什么办法吗?这些文件必须位于egg

3 个答案:

答案 0 :(得分:3)

egg个文件刚刚重命名为.zip文件。

您可以使用zipfile库打开鸡蛋并提取或阅读您需要的文件。

import zipfile

zip = zipfile.ZipFile('/path/to/file.egg', 'r')

# open file from within the egg
f = zip.open('synonyms.csv', 'r')
txt = f.read()

答案 1 :(得分:1)

您可以尝试在这里做两件不同的事情:

  • 将数据文件视为包的一部分,如Python模块,并在运行时访问它们,就像您的包是普通的目录树一样,即使它不是。
  • pip install时间安装的数据文件安装到您可以正常访问的位置。

PyPA / setuptools文档中the section on data files解释了这两个问题。我想你想要第一个,这在Accessing Data Files at Runtime的小节中有所涉及:

  

通常,现有程序会操纵包的__file__属性,以便找到数据文件的位置。但是,此操作与基于PEP 302的导入挂钩不兼容,包括从zip文件和Python Eggs导入。如果您使用的是数据文件,强烈建议您使用pkg_resources pkg_resources来访问它们。 setuptools模块作为setuptools的一部分进行分发,因此如果您使用__file__分发您的包,则没有理由不使用其资源管理API。另请参阅ResourceManager API,以获取将pkg_resources转换为使用try的代码的快速示例。

按照这个链接,你会发现看起来像一些狡猾的旧PEAK文档,但这只是因为他们真的是狡猾的旧PEAK文档。有一个Accessing Package Resources,一旦你找到它就会更容易阅读和导航。

正如它所说的那样,你可以 get_data使用pkg_resources(它将在egg / zip中工作)然后回退到访问文件(这将在从源代码运行),但最好使用path = os.path.join(__file__, 'Wordproject/WordProject/Repository/DataBank/', datathingy) with open(path) as f: for line in f: do_stuff(line) 中的包装器。基本上,如果你的代码是这样做的:

path = 'Wordproject/WordProject/Repository/DataBank/' + datathingy
f = pkg_resources.resource_stream(__name__, path)
for line in f:
    do_stuff(line.decode())

...你会改变它:

resource_stream

请注意,TextIOWrapper文件始终以二进制模式打开。因此,如果您想将它们作为文本阅读,则需要在它们周围包裹{{1}},或者解码每一行。

答案 2 :(得分:0)

基于documentation,我们可以通过多种方式读取文件的内容。

解决方案1:直接将文件内容读入内存。

无需在本地提取文件。

import zipfile, tempfile
tfile = tempfile.NamedTemporaryFile()
with zipfile.ZipFile('/path/to/egg.egg') as myzip:
    with myzip.open('relative/path/to/file.txt') as myfile:
        tfile.write(myfile.read())

# .. do something with temporary file

tfile.close()

现在tfile是您的本地临时文件句柄。它的名称为tfile.name,所有文件操作(例如open(tfile)等)都照常运行。必须在最后调用tfile.close()才能关闭句柄。

myfile.read()本身可以读取文件的内容,但是一旦退出上下文,我们将失去myfile句柄。因此,如果需要传递文件内容以进行其他操作,则将文件内容复制到一个临时文件中。

解决方案2:本地提取鸡蛋成员

zipfile提供了用于提取特定成员的API

import zipfile
x = zipfile.ZipFile('/path/to/egg.egg')
x.extractall(path='temp/dest/folder', members=['path/to/file.txt'])

解决方案3:提取整个鸡蛋

另一种解决方案是将鸡蛋提取到临时文件夹中,然后读取文件。可以在命令行中如下提取鸡蛋

python -m zipfile -e path/to/my.egg ./temp_destination