py2app打包Python应用时如何访问包内非Python格式资源文件
py2app内置资源访问解决方案
方案1:直接读取压缩包内资源(无需修改现有打包配置)
你开启include_package_data=True后资源被打进python包压缩包是正常现象,不需要手动解压,可以用Python标准库importlib.resources直接读取:
# Python 3.9+ 可用 from importlib.resources import files # 读取writer/data/extra_data/content.txt文本内容 txt_content = files("writer.data.extra_data").joinpath("content.txt").read_text(encoding="utf-8") # 读取二进制文件比如压缩包 zip_content = files("writer.data").joinpath("extra_data.zip").read_bytes() # 读取嵌套目录文件 nested_content = files("writer.data.extra_data.nested_folder").joinpath("content.txt").read_text()
注意:需要在项目根目录新增
MANIFEST.in文件,写入以下内容确保非py文件被正确收录:recursive-include writer/data *
方案2:资源解压到应用目录,支持直接路径访问
如果你需要将资源路径传给其他组件(比如加载本地html到浏览器、需要修改资源文件等场景),可以通过DATA_FILES配置将资源直接复制到应用的Resources目录:
第一步修改setup.py
from setuptools import setup import glob import os def get_data_files(target_dir, source_dir): data_files = [] for root, dirs, files in os.walk(source_dir): file_list = [os.path.join(root, f) for f in files] target_path = os.path.join(target_dir, os.path.relpath(root, source_dir)) data_files.append((target_path, file_list)) return data_files APP = ['main.py'] # 把writer/data下所有文件打包到应用Resources/writer/data目录 DATA_FILES = get_data_files('writer/data', 'writer/data') OPTIONS = {} setup( app=APP, data_files=DATA_FILES, include_package_data=True, options={'py2app': OPTIONS}, setup_requires=['py2app'], )
第二步运行时获取资源路径
import sys import os if getattr(sys, 'frozen', False): # 打包后运行,获取Resources目录路径 RES_BASE = os.path.join(os.path.dirname(sys.executable), '..', 'Resources') else: # 开发环境直接用项目根路径 RES_BASE = os.path.dirname(os.path.abspath(__file__)) # 拼接资源路径 content_path = os.path.join(RES_BASE, 'writer', 'data', 'extra_data', 'content.txt') # 直接用普通方式读取 with open(content_path, 'r', encoding='utf-8') as f: content = f.read()
方案选择建议
- 仅需要读取静态资源,不需要真实文件路径的场景,优先选方案1,无需修改打包配置
- 需要真实文件路径、需要修改资源的场景,选方案2
内容的提问来源于stack exchange,提问作者JaWeilBaum
相关产品推荐
相关产品推荐

