当前位置: 首页 > 科技观察

如何用Python正确读取资源文件

时间:2023-03-22 14:54:06 科技观察

我们知道,当你把一个资源文件和一个.py文件放在一起时,你可以直接在.py文件中使用文件名来读取。例如:withopen('test.txt')asf:content=f.read()print('文件中的内容为:',content)运行效果如下图所示:但请注意,这里我我直接运行读取.py文件。如果把资源文件放在一个包里,然后我们在外面调用这个包里的.py文件呢?试一下:可以看到Python现在找不到这个文件了。这是因为我们的入口程序在~/get_title文件夹下,而test.txt文件在~/get_title/util文件夹下。因为我们运行的是main.py,Python会去~/get_title文件夹中找test.txt,自然找不到。如果您要引用包中的其他模块,则可以使用相对路径。比如引用同一个包中名为sql_util.py的conn对象,我们可以直接写成from.sql_utilimportconn。但是,使用相对路径是无法读取资源文件的,如下图所示:有一种比较笨的方法是获取当前运行的代码行所在的文件夹,然后拼出资源文件的完整路径。修改read.py文件:importosdefread_file():current_folder=os.path.dirname(__file__)resource_path=os.path.join(current_folder,'test.txt')withopen(resource_path)asf:content=f.read()print('文件中的内容为:',content)运行效果如下图:但是这样写有点麻烦。如果你的Python版本不低于3.7,那么可以使用importlib.resources来快速读取资源文件:fromimportlibimportresourceswithresources.open_text('packagename','resourcepath')asf:content=f.read()运行效果为如下如图:如果你不是读取文本文件,那么可以将resources.open_text改为resources.open_binary来读取二进制文件。但需要注意的是,资源文件一定要放在包的根目录下。只有这样,才能正确阅读。如果资源文件在包内的子目录下,则无法直接读取importlib.resources。比如我们的包是util,有一个文件夹叫deep_folder,资源文件test.txt放在deep_folder里面。这时候如果我们要读取这个资源文件,就必须在deep_folder文件夹下创建一个__init__。py,也把它变成一个包。然后修改read.py的代码:fromimportlibimportresourcesfrom.importdeep_folderdefread_file():withresources.open_text(deep_folder,'test.txt')asf:content=f.read()print('文件中的内容为:',content)把deep_folder作为一个模块导入,然后将这个模块作为resources.open_text的第一个参数。只有这样才能正确读取,如下图所示: