Skip to content

应用文件以未打包形式存在于只读包中;存储目录重构 ​

INFO

本指南以 Flet 0.86.0 为准,内容是最准确的。后续版本可能会新增 API 或增加额外的迁移路径。

破坏性变更与废弃索引列出了为每个版本编写的指南。

概述 ​

Flet 0.86.0(配合 serious_python 4.0.0)改变了打包应用分发 Python 文件的方式,以及应用读取和写入数据的位置:

  • 应用文件以未打包形式存在于应用包中,紧邻 Python 标准库和 site-packages,位于 macOS / iOS / Windows / Linux 上。没有首次启动时的 app.zip 解包。在 Android 上,应用以 APK 内一个存储型的 app.zip 资产形式分发,并在安装/更新后首次启动时解包一次(按版本键)到应用的 files 目录。Web(Pyodide)不变。
  • 应用目录现在只读(签名的 .app、iOS 包、Program Files、APK)。
  • Python 程序的当前工作目录从应用目录移到了一个可写的、应用私有的数据目录,以 FLET_APP_STORAGE_DATA 暴露。
  • FLET_APP_STORAGE_DATA 现在映射到操作系统的应用支持目录(一个 data 子目录),而非用户的 Documents 文件夹。
  • 存储环境变量现在是一套干净的三级集合:FLET_APP_STORAGE_DATA(持久)、新增的 FLET_APP_STORAGE_CACHE(可重新生成)和 FLET_APP_STORAGE_TEMP(现在是操作系统临时目录,以前是缓存目录)。
  • flet run(开发模式)现在将工作目录设置为一个隐藏的、已被 git 忽略的 <project>/.flet/storage/data,与构建出的应用一致。

背景 ​

此前你的 Python 源码被压缩进 app/app.zip,作为一个 Flutter 资产分发,并在首次启动时于运行时解包——而标准库和 site-packages 已经以未打包形式存在于包内。把应用文件的处理提升到 serious_python 中,去掉了首次启动的解压和哈希记账工作,并让你的代码与标准库处于同一位置。因为那个位置是只读的,工作目录必须移到某个可写之处——而应用数据天然的家就是操作系统的应用支持目录,它在每个平台上都是应用私有的(不会污染 Documents,也无需手动限定作用域)。

迁移指南 ​

把数据写入存储目录,而非代码旁边 ​

应用目录是只读的。相对写入会解析到当前工作目录,现在它是 FLET_APP_STORAGE_DATA(一个可写、持久、应用私有的目录)。open("app.db", "w") 和 sqlite3.connect("app.db") 仍然能工作——只是文件现在落在数据目录,而不是你的 .py 文件旁边,并且现在会在应用更新之间持久保存。

通过 __file__ 读取分发的文件,而非相对路径 ​

对你与应用一起打包的文件的相对读取(例如 `open("seed.json"))不再会解析到你的应用文件夹。请相对于你的模块来读取打包的数据:

python
from pathlib import Path

SEED = Path(__file__).parent / "seed.json"
data = SEED.read_text()

或者使用 importlib.resources,又或者把文件放在你的 Flet assets/ 目录下,并通过 FLET_ASSETS_DIR 解析它。

存储环境变量 ​

变量含义生命周期
FLET_APP_STORAGE_DATA持久的应用数据(= 工作目录)永不自动删除;会被备份
FLET_APP_STORAGE_CACHE可重新生成的缓存(新增)在存储压力下操作系统可能会清除
FLET_APP_STORAGE_TEMP操作系统临时 / 暂存(已变更——以前是缓存目录)最易失;可能在两次启动之间消失

如果你依赖 FLET_APP_STORAGE_TEMP 来存放应当留存的数据(它曾经是缓存目录),请改用 FLET_APP_STORAGE_CACHE(或用于必须保留数据的 FLET_APP_STORAGE_DATA)。

物理位置 ​

FLET_APP_STORAGE_DATA(= 工作目录):

平台位置
Windows%APPDATA%\<company>\<product>\data(例如 C:\Users\<User>\AppData\Roaming\<company>\<product>\data)
macOS~/Library/Application Support/<bundle-id>/data(沙盒应用:重定向进应用容器)
Linux${XDG_DATA_HOME:-~/.local/share}/<app-id>/data
iOS<app-sandbox>/Library/Application Support/<bundle-id>/data
Android/data/data/<package>/files/data
flet run(开发)<project>/.flet/storage/data

FLET_APP_STORAGE_CACHE 和 FLET_APP_STORAGE_TEMP:

平台FLET_APP_STORAGE_CACHEFLET_APP_STORAGE_TEMP
Windows%LOCALAPPDATA%\<company>\<product>%TEMP%(…\AppData\Local\Temp)
macOS~/Library/Caches/<bundle-id>$TMPDIR(例如 /var/folders/.../T/)
Linux${XDG_CACHE_HOME:-~/.cache}/<app-id>系统临时目录($TMPDIR,回退为 /tmp)
iOS<app-sandbox>/Library/Caches/<bundle-id><app-sandbox>/tmp
AndroidgetCacheDir()(/data/data/<package>/cache)与 CACHE 相同(getCacheDir())
flet run(开发)<project>/.flet/storage/cache<project>/.flet/storage/temp

flet run 开发存储 ​

flet run 现在会创建一个隐藏的 <project>/.flet/ 目录(带有 storage/{data,cache,temp}),并将应用的工作目录设为 .flet/storage/data 来运行,因此开发时的行为就像构建出的应用(包括上面「读取分发文件」的变更)。该目录会写入自己的 .gitignore,被 Git 自动忽略;旧的可见 storage/ 目录不再使用。

时间线 ​

  • 变更于:0.86.0

参考 ​


关注我,学习大模型、大数据、Python等热门技术。