Flet 0.83.0 版本解读更快的控件 diff、更精简的打包与通往 1.0 的工程化之路【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/fletFlet 0.83.0 是一次面向地基的发布它重写了命令式与声明式两种编程风格下的控件 diff 机制将桌面客户端二进制与构建模板从 PyPI 迁移到 GitHub Releases并引入基于Annotated类型的声明式字段校验。本文将以该版本发布公告为骨架结合当前仓库中的 Python SDK 源码逐项拆解这些改进的实现原理、升级步骤与对日常开发的实际影响帮助你理解 0.83.0 的底层变化并在自己的应用中平滑升级。如何升级到 0.83.00.83.0 的升级方式与以往保持一致根据你使用的依赖管理工具选择对应命令使用 pip 直接升级含全部平台扩展pip install flet[all] --upgrade使用 uv 并维护pyproject.toml希望整体同步所有依赖uv sync --upgrade只想升级 Flet 相关包框架本体、CLI、桌面运行时、Web 运行时保持其他依赖不动uv sync --upgrade-package flet \ --upgrade-package flet-cli \ --upgrade-package flet-desktop \ --upgrade-package flet-web注意0.83.0 起flet-desktop包的结构发生了根本变化见下文打包重构章节升级后首次运行桌面应用时会有一个一次性初始化下载过程这属于正常行为。更快的控件 diff从遍历全屋到只查拨动的开关Flet 应用本质上是一个 Python 到 Flutter 的桥每次调用page.update()或重建声明式组件时框架都要计算一个 diff——即哪些属性发生了变化、需要同步给 Flutter 客户端的集合。0.83.0 之前这个过程是无差别全量比较0.83.0 则针对命令式和声明式两种编程风格分别做了机制性重构。命令式应用Prop描述符与稀疏脏标记改动前每次page.update()都会遍历控件上的所有属性并与上一份快照逐一比较哪怕你只改了一个属性。一个拥有 20 个属性的控件即使只改了 1 个Flet 也要把 20 个全部比较一遍。改动后新的Prop描述符负责追踪自上次 diff 以来哪些属性被真正写入过。当你执行button.text Click me时只有text被标记为 dirty下一次page.update()只把 dirty 属性发给 Flutter其余属性全部跳过。打个比方以前是每层楼每个房间都巡检一遍现在只检查你真正拨动过的那几个开关。从源码看这一机制的核心实现在 value_types.pyProp是一个实现了__get__/__set__的数据描述符它把非默认值稀疏地存入控件的_values字典赋值时如果新值等于声明默认值直接丢弃恢复稀疏性如果新值与旧值相等直接短路返回无变化则不触发任何同步否则写入_values并标记obj._dirty[self.name]随后触发_notify通知。而_values与_dirty这两个内部字典定义在 base_control.py并在__post_init__末尾执行self._dirty.clear()base_control.py保证构造过程不算变更——只有构造之后的显式赋值才会进入 diff 视野。这意味着冻结frozendiff 快路径只需取两个对象_values字典的键并集而无需扫描所有已声明字段。声明式应用value装饰器与按内容比较改动前声明式组件重建时Flet 会逐一比较新旧控件树的每个字段——包括Alignment、BorderRadius、BoxDecoration这类嵌套值对象。由于每次 build 都会重新创建这些对象即使内容一模一样它们按对象身份比较时也永远看起来是新的导致整个子树无法被跳过。改动后约 150 种数据类型改用新的value装饰器使其按内容而非身份进行相等比较再配合先检查结构性变化、再只比较真正有差异的字段的两遍 diff未变化的子树可以被整体跳过。value装饰器的实现在 value_types.py它本质上是一个dataclass_transform装饰器内部先应用dataclass再通过_install_props()把公开字段替换为Prop描述符、记录非 Prop 的结构性字段并在__init__中注入_values/_dirty后于构造末尾清空 dirty 标记。同时它把类注册为Value的虚拟子类value_types.py使 diff 机制可以通过isinstance(obj, Value)快速识别这类值类型。该模块之所以独立成文件正是为了避免与base_control形成循环导入Duration、Alignment等值类型被base_control间接引用。基准数据官方在 Python 3.14.2、Apple Silicon 环境下测得详见发布公告场景提升幅度冻结控件20 字段、改动 2 个100–300 个控件3.2–3.4× 更快混合 keyed/unkeyed 列表1.9–2.0× 更快非冻结重建列表2.9–4.5× 更快Sunflower 声明式示例500 粒种子6.7× 更快其中作为基准的 Sunflower 示例在仓库中位于 sunflower/main.py是一个用滑块实时重算声明式布局的动画应用Seed数据类与AppModel通过ft.Observable驱动状态SeedView组件被ft.memo包裹构建了由数百个带 key 的Container组成的Stack当前仓库中该示例的种子总数上限为 250公告基准中记载为 500量级一致。ft.memo正是依赖值类型按内容比较来避免无谓重建的关键场景感兴趣的读者可以对照 memo.py 阅读。更智能的.update()自动更新不再重复触发旧版本中Flet 会在每个事件处理函数执行结束时自动调用一次page.update()。如果你的处理函数里已经显式调用过.update()例如先弹出一个 spinner 再开始耗时工作框架就会在末尾再触发一次冗余 update可能造成视觉闪烁或无效工作。0.83.0 起框架会追踪处理函数执行期间是否已经调用过.update()调用过则末尾的自动更新被跳过。这一改动还带来一个重要的兼容性收益——从 Flet 0.28.3没有自动更新机制的版本原样迁移过来的应用无需任何改动即可获得与旧版本一致的行为。对于追求精细控制的开发者这意味着你既可以利用事件末尾自动刷新的便利也可以在关键路径上显式update()并放心它不会被重复执行。声明式字段校验AnnotatedV规则集0.83.0 为控件字段引入了声明式校验能力字段可以内联声明校验规则替代在__init__或before_update()里手写检查代码。规则使用 Python 标准的Annotated类型元数据表达from typing import Annotated from flet.core.validation import V entries: Annotated[list, V.or_(V.empty, V.min_length(3))]这条声明表达的含义是entries字段要么为空、要么长度至少为 3二者满足其一即通过校验。约束与字段定义写在一起让人一眼就能看出该字段的不变量。这一特性在当前仓库的 SDK 中已经有实际应用。例如 control.py 中所有控件基类共有的expand字段expand: Annotated[ Optional[Union[bool, int]], V.instance_of((bool, int)), ] None当传入非bool/int类型时赋值阶段即抛出ValueError其 docstring 中的Raises: ValueError正是由该规则驱动的。同样地opacity字段使用了V.between(0.0, 1.0)约束取值范围control.py。V规则构建器定义在 validation.py它提供一系列静态方法返回可附加到Annotated[...]字段或类级__validation_rules__的FieldRule/ClassRule实例。以组合规则V.or_为例其实现会校验传入参数均为FieldRule、至少一个规则否则抛出ValidationDeclarationError并在运行时按声明顺序求值、任一规则通过即成功validation.py。大多数字段级规则在字段注解为可选类型时会自动放行None避免与未设置状态冲突。配合规则集弃用字段还能通过V.deprecated规则validation.py在赋值时发出一次性弃用警告并携带version、delete_version、docs_reason等元数据——文档工具会自动为弃用字段生成提示性告示省去了手工维护文档的负担。打包重构一客户端二进制从 PyPI 迁移到 GitHub Releases此前Flet 的桌面客户端面向 Windows、macOS、Linux 的 Flutter 运行时被打进 PyPI wheel 里分发导致 wheel 体积巨大、持续消耗 PyPI 存储空间。从 0.83.0 起这一做法被彻底改变桌面客户端改为首次运行时从 GitHub Releases 下载并缓存在本机~/.flet/client/flet-desktop包变成一个单一、体积小巧、与平台无关的 wheel。这对开发者意味着安装更快pip install flet下载的是小体积 wheel不再夹带平台特定二进制包更统一独立的flet-desktop-light包被移除通过FLET_DESKTOP_FLAVOR环境变量或pyproject.toml中的[tool.flet]配置在 light/full 两种风味间选择Linux 上未指定时默认使用 light 风味支持离线环境通过FLET_CLIENT_URL环境变量指向本地镜像即可在无法访问 GitHub 的内网环境中完成客户端获取。源码印证了完整的解析与下载链路。在 flet-desktop/src/flet_desktop/init.py 中__get_desktop_flavor()按以下优先级解析风味FLET_DESKTOP_FLAVOR环境变量 → 当前目录pyproject.toml中[tool.flet].desktop_flavor→ 默认值Linux 为light其他平台为full。下载逻辑在__download_flet_client()同文件 L309-L331默认 URL 由包内嵌入的版本号构造https://github.com/flet-dev/flet/releases/download/v{ver}/...并可用FLET_CLIENT_URL整体覆盖ensure_client_cached()则负责管理~/.flet/client/缓存目录同时兼容 PyInstaller 打包场景下包内附带归档的降级路径。此外Linux 客户端选择还会结合 glibc 版本与发行版 ID 挑选匹配的构建目标同文件 L99-L124。打包重构二构建模板迁移到 GitHub Releases与此配套原先独立的flet-build-template与flet-app-templates仓库被合并进 Flet 主仓库构建模板改为以 zip 归档形式挂载在每次 GitHub Release 上。当你执行flet build或flet create时CLI 会下载与你当前安装的 Flet 版本精确匹配的模板 zip——版本被锁定即使是预发布版本也一样。这彻底消除了框架与构建模板版本不匹配的老问题。对于稳定版发布fletFlutter 包照常发布到 pub.dev而对于预发布版本构建模板会通过 Git 依赖直接引用精确的 commit SHA——从而保证flet build编译所用的 Flutter 代码与你的 Python 包版本严格一一对应。更好的发布可追溯性0.83.0 强化了版本追溯能力GitHub 预发布Pre-releases每个开发构建都会生成一个 GitHub Release如v0.83.0.dev6045。你可以直接浏览预发布列表精确了解每个开发版本修复了哪些问题、引入了哪些特性不再需要猜测某个 bug 修复是否已进入最新 dev 版本。Issue/PR 里程碑Milestonesissue 与 PR 现在会被指派到里程碑。想确认某个 issue 何时被修复查看其里程碑即可得知对应的发布版本号。通往 1.0工程化与质量基础设施0.83.0 的另一面是可持续性投入这直接服务于 Flet 1.0 的目标端到端自动化CI 流水线覆盖构建、测试、打包、发布全流程。每次推送到main都会触发全平台二进制构建、测试套件运行、所有目标的flet build验证以及向 GitHub 和 pub.dev 发布 dev 版本全程无人工步骤。全面集成测试目前已在 macOS 上运行 200 项集成测试分布在 12 个并行测试套件中覆盖核心控件、Material 与 Cupertino 组件、服务、主题、扩展和示例应用完整跑一遍约需 85 分钟能够在缺陷到达用户之前捕获回归。其他平台的集成测试套件正在推进中仓库中示例的截图金样目录如 packages/flet/integration_tests/examples/apps/golden/macos 即为该体系的产物。文档体系升级Flet 文档将回归 Docusaurus 构建带来更好的阅读体验、更优的搜索和更顺畅的贡献流程。其他变更与 Bug 修复0.83.0 还包含一批值得关注的功能与修复可定制滚动条#6282滚动条的样式与行为可配置。可滚动的ExpansionPanelList#6294面板列表内容超出视口时可滚动。SharedPreferences支持更多类型#6267现在支持int、float、bool和list[str]。源码中其类型别名定义为SharedPreferencesValueType: TypeAlias Union[str, int, float, bool, list[str]]shared_preferences.pyset()方法会校验值类型并对不支持的类型抛出ValueErrorshared_preferences.py。对齐 Python 与 Dart 默认值#6330跨所有包统一两侧的默认参数。修复ReorderableListView事件反序列化#6315on_reorder_start/on_reorder_end的事件载荷得到修正。从源码看这两个事件的 payload 是OnReorderEventreorderable_list_view.py其中old_index仅在on_reorder_start/on_reorder时非空new_index仅在on_reorder/on_reorder_end时非空本次修复保证了两者能被正确解析。跳过带pyproject.toml应用的 micropip 加载#6300Web 端初始化路径优化。总结Flet 0.83.0 是典型的地基型版本Prop描述符 value装饰器让命令式与声明式应用的 diff 效率获得数倍提升AnnotatedV把校验从手写逻辑变成声明式约束客户端二进制与构建模板迁移到 GitHub Releases 让安装更轻、版本更可控而预发布与里程碑机制让每个构建都可追溯。这些底层改进具有复利效应——后续每个版本都会建立在更快、更可靠的基础上。对于应用开发者本版本的实践要点可以概括为三条升级时记得用--upgrade-package只升 Flet 相关包升级后首次运行桌面应用会有一次性客户端下载如果处于内网环境提前用FLET_CLIENT_URL和FLET_DESKTOP_FLAVOR或[tool.flet]配置完成部署规划。【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考