从python egg访问文件

问题描述 投票:2回答:3

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

  • 这些文件存在于文件夹结构Wordproject/WordProject/Repository/DataBank/
  • 我在RepositoryReader路上有一个Wordproject/WordProject/Repository/
  • 我编写了一个代码来拉出RepositoryReader的当前位置,然后寻找一个名为subdirectoryDataBank并在那里寻找3个文件。

问题是当我从代码中创建一个egg,然后运行它,

我的代码给了我错误:

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

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

python egg
3个回答
1
投票

您可以尝试在此处执行两项不同的操作:

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

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

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

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

正如它所说,你可以使用try get_data(它将在egg / zip中工作),然后回退到访问文件(从源代码运行时可以工作),但你最好使用pkg_resources中的包装器。基本上,如果你的代码是这样做的:

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,或者解码每一行。


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()

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:提取整个鸡蛋

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

python -m zipfile -e path/to/my.egg ./temp_destination
© www.soinside.com 2019 - 2024. All rights reserved.