You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

所有文件在文件夹根目录下,如何用importlib.resources访问文件资源?

解决zipapp打包后读取根目录config.json的问题

为什么直接用路径找不到文件?

用python -m zipapp打包后,脚本是在ZIP归档内部运行的,此时用"config.json"这种相对路径,Python会去当前工作目录找文件,而不是ZIP包内部的根目录,所以必然找不到。

关于importlib.resources的使用细节

1. 包名与__init__.py的要求

importlib.resources是专门用来读取Python包内资源的工具,它要求你的代码所在目录是一个合法的Python包——也就是必须有__init__.py(空文件就行)。

如果你的所有代码都在根目录(没有子文件夹),那这个根目录就是你的包,包名就是你打包时的文件夹名称。比如你把所有文件放在my_script文件夹里,打包时执行python -m zipapp my_script,那代码里的包名就写"my_script"。

要是你直接在当前目录打包(没单独建文件夹),这种情况包名可以用''(空字符串),但还是得先建__init__.py才能让importlib.resources识别。

2. 不用纠结包名的替代方案

嫌搞包名麻烦?直接用__file__判断运行环境,读取ZIP包内的文件就行,不用__init__.py:

import os
import zipfile

# 获取当前脚本的绝对路径
current_script = os.path.abspath(__file__)
# 判断是否在ZIP包(pyz文件)里运行
if current_script.endswith('.pyz'):
    with zipfile.ZipFile(current_script, 'r') as zip_ref:
        with zip_ref.open('config.json') as f:
            config_content = f.read().decode('utf-8')
else:
    # 本地直接运行__main__.py时,读当前目录的config.json
    with open('config.json', 'r') as f:
        config_content = f.read()

这个方法不管是本地测试还是打包后运行都能正常工作。

3. 为什么__package__是空的?

直接运行python __main__.py时,脚本是作为主程序执行的,不是作为包的模块被导入,所以__package__为空是正常现象,依赖这个变量的方法在这里行不通。

用importlib.resources的标准流程

  1. 把所有脚本和config.json放进一个单独的文件夹,比如my_app。
  2. 在my_app里创建空的__init__.py。
  3. 打包:执行python -m zipapp my_app,生成my_app.pyz。
  4. 在__main__.py里写:
from importlib.resources import open_text

with open_text('my_app', 'config.json') as f:
    config = f.read()

内容的提问来源于stack exchange,提问作者u84six

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 18:18:50