嗨,我正在使用python包装。我有3个non-code
文件,即['synonyms.csv', 'acronyms.csv', 'words.txt']
。
Wordproject/WordProject/Repository/DataBank/
中RepositoryReader
路上有一个Wordproject/WordProject/Repository/
班RepositoryReader
的当前位置,然后寻找一个名为subdirectory
的DataBank
并在那里寻找3个文件。问题是当我从代码中创建一个egg
,然后运行它,
我的代码给了我错误:
无法在X:\ 1找到该文件。项目\ Python的\ Wordproject \ VENV \ LIB \站点包\ Wordproject-1.0-py3.6.egg \ Wordproject \库\数据库\ synonyms.csv
如果路径是鸡蛋,它无法获取文件或从路径读取文件。它有什么办法吗?这些文件必须在egg
中。
您可以尝试在此处执行两项不同的操作:
pip install
时间的其他位置,安装到您可以正常访问的位置。两者都在PyPA / the section on data files文档中的setuptools
中进行了解释。我想你想要第一个,这在Accessing Data Files at Runtime的小节中有所涉及:
通常,现有程序操纵包的
__file__
属性以查找数据文件的位置。但是,此操作与基于PEP 302的导入挂钩不兼容,包括从zip文件和Python Eggs导入。强烈建议,如果您使用的是数据文件,则应使用ResourceManager API的pkg_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
,或者解码每一行。
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()
基于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