
marimo batch API 实战指南用 HTML 模板与mo.ui.batch批量组合交互控件【免费下载链接】marimoA reactive notebook for Python — run reproducible experiments, query with SQL, execute as a script, deploy as an app, and version with git. Stored as pure Python. All in a modern, AI-native editor.项目地址: https://gitcode.com/GitHub_Trending/ma/marimo导读mo.ui.batch是 marimo 提供的一种组合式 UI 元素它把一段带占位符的 HTML/Markdown 模板与若干个 UI 元素绑定在一起模板负责排版与描述文字UI 元素负责交互输入二者合成为一个整体输出。本文基于 docs/api/inputs/batch.md 编写结合源码实现与测试用例讲解 batch 的两种创建方式、模板插值规则、value数据结构、元素访问 API、回调机制以及典型实战场景帮助你用少量代码构建日期范围选择用户信息表单这类自定义交互组件。一、batch 是什么模板与控件的组合器在 marimo 中每个mo.ui.*元素都同时具有两个面展示面一段 HTML决定用户在界面上看到什么和值面一个 Python 值决定后续单元格能拿到什么数据。普通做法是一个单元格放一个控件但当你需要多个控件以特定排版组合出现时batch提供了一种更优雅的抽象。batch的核心思想见 源码 batch.pyConvert an HTML object with templated text into a UI element.即把一段带有{placeholder}占位符的 HTML/Markdown 文本转换成一个 UI 元素。模板中的每个占位符都对应一个子 UI 元素最终输出由模板排版 子控件渲染共同构成而整个 batch 的value是一个dict键为占位符名值为对应子元素的值。从源码类继承关系看batch继承自_batch_base而_batch_base继承自UIElement[dict[str, JSONType], dict[str, object]]——前端的类型是{label value update}Python 侧的类型是dict映射 label 到 value。前端通过marimo-dict标签渲染对应 DictPlugin.tsx 插件。batch 与 dictionary 的区别源码中batch与ui.dictionary同源都基于marimo-dict前端组件且共用validate_and_clone校验逻辑但定位不同ui.dictionary用一个 Python dict 组织控件仅用于布局/分组没有模板文字ui.batch用 HTML/Markdown模板文字组织控件适合文字描述 控件混合排版的场景如从 {start} 到 {end}。二、两种创建方式方式一Html.batch()链式调用推荐任何Html对象包括mo.md()和mo.html()的返回值都带有一个batch方法定义在 hypertext.pydef batch(self, **elements: UIElement[Any, Any]) - batch_plugin:示例即文档中marimo-embed演示的核心逻辑import marimo as mo app.cell def __(): el mo.md({start} → {end}).batch( startmo.ui.date(labelStart Date), endmo.ui.date(labelEnd Date) ) el return app.cell def __(): el.value return运行效果单元格内渲染出mo.ui.date控件模板文本{start} → {end}中的占位符被两个日期控件替换在另一个单元格中读取el.value得到{start: date1, end: date2}。方式二直接实例化mo.ui.batch当模板与元素需要分开定义、或元素需要动态构造时可以直接实例化类参考 batch.py 的__init__签名markdown mo.md( - Whats your name?: {name} - When were you born?: {birthday} ) user_info mo.ui.batch( markdown, {name: mo.ui.text(), birthday: mo.ui.date()} ) user_info.value # {name: ..., birthday: datetime.date(...)}两种方式完全等价——mo.md(...).batch(name..., birthday...)内部就是把selfHtml 对象和元素字典传给batch_plugin构造函数hypertext.py。注意直接实例化时第二个参数必须是Mapping[str, UIElement]且值必须全部是 UI 元素详见下文类型校验。三、模板插值规则与类型校验占位符如何被替换batch.__init__内部执行的关键一步batch.pyelements validate_and_clone(elements) super().__init__( htmlHtml(self._html.text.format(**elements)), ... )即先把元素字典做校验与克隆然后调用 Python 字符串的str.format(**elements)将模板中的{name}、{birthday}替换为子元素的 HTML 渲染。由于每个UIElement都有_mime_/HTML 呈现能力format之后得到的是一段完整的 HTML 片段——这就是为什么 batch 的输出天然是模板排版与控件混排的界面。只接受 UIElementValueError 保护validate_and_clonebatch.py会逐个检查传入值是否为UIElement实例否则抛出ValueError: .batch only accepts UIElements as arguments. Invalid keys: ...测试 test_batch.py 明确覆盖了这些非法情形md(Example {thing}).batch(thingthing) # 字符串 → 抛 ValueError md(Example {thing}).batch(thing42) # 数字 → 抛 ValueError md(Example {thing}).batch(thing{key: value}) # dict → 抛 ValueError元素会被克隆validate_and_clone对每个合法元素调用_clone()返回的是具有不同 ID 的副本ui_element.py 中_clone的文档明确说明 The clone will not synchronize with the original element。测试同样验证了这一点cloned[a]._id ! a._id # 克隆体与原元素 ID 不同这意味着你在模板中使用的元素与外界同名变量是两个独立实例批内元素的变更不会反向污染原变量同时批内子元素通过_register_as_view(parentself, keykey)batch.py注册为父元素的视图从而与父元素建立联动关系。四、读取与访问value、elements 与索引.value批量值的字典batch的value是一个只读dict键为占位符名值为对应子元素当前值。文档示例中单独一个单元格写el.value即可展示el.value # {start: datetime.date(2026, 9, 1), end: datetime.date(2026, 9, 12)}实现上_batch_base._convert_valuebatch.py在收到前端更新时会遍历value中的每个键找到对应子元素仅当值确实变化时才调用element._update(v)同步子元素状态最终聚合出{key: element._value}字典——既保证数据一致也避免无效更新触发多余重算测试test_update_on_frontend_value_change_only验证了重复更新同一值只生效一次。.elements子元素字典通过.elements属性可以拿到批内全部子元素克隆后的副本el.elements # {start: UIElement, end: UIElement} el.elements[start] # 直接操作 start 元素类字典访问协议batch实现了完整的映射协议batch.py可以像 dict 一样使用len(el) # 2元素个数 el[start] # 按 key 取子元素 start in el # True成员判断 list(el) # [start, end]迭代键 el.get(missing, None) # 带默认值的安全取值 el.items() # 键值对视图 el.values() # 子元素视图五、on_change 回调与嵌套场景批级回调batch支持on_change参数签名与普通 UI 元素一致batch.pydef handle(values: dict) - None: print(updated:, values) b mo.md({name}).batch( namemo.ui.text(), on_changehandle, )回调接收的是整个 batch 的值字典dict[str, object]在批内任意子元素变化时触发。需要说明的是示例源码中的batch构造函数目前暴露的是html, elements, on_change三个参数label参数属于内部基类_batch_base的构造参数默认对外通常无需传入。嵌套场景中的回调保持一个值得注意的实现细节当 batch 作为子元素嵌套进ui.array等容器时子元素的on_change仍然引用原始对象而不是深拷贝后的对象。这是对 issue 的回归修复test_batch.pymodels [Model(i) for i in range(3)] view ui.array([ ui.batch(Html({box}), elements{box: ui.checkbox(on_changem.set_state)}) for m in models ]) view._update({0: {box: True}}) assert models[0].state is True # 修改的是原始 Model因此即便控件被 batch 包裹并克隆on_change闭包中捕获的外部状态如数据库连接、业务对象依然指向正确的实例适合在批量数据行编辑等场景中使用。六、完整实战示例日期范围选择器结合 examples/ui/batch.py 中仓库自带的官方示例一个典型的 batch 应用是日期范围选择import marimo as mo app marimo.App(widthmedium) app.cell def _(): import marimo as mo return (mo,) app.cell def _(mo): element mo.md({start} → {end}).batch( startmo.ui.date(labelStart), endmo.ui.date(labelEnd), ) element return (element,) app.cell def _(element): # 在另一个单元格读取/使用批量值 start, end element.value[start], element.value[end] mo.md(f**报告区间**{start} → {end}共 {(end - start).days} 天) return if __name__ __main__: app.run()运行方式# 方式一作为交互式 notebook 启动 marimo edit examples/ui/batch.py # 方式二直接作为脚本运行 python examples/ui/batch.py更多组合思路batch 的通用模式是模板 任意 UI 元素因此可以自由组合不同类型的控件# 混合控件文本输入 滑块 下拉 report mo.md( ### 报表配置 - 报表标题{title} - 置信区间{ci} - 图表类型{chart} ).batch( titlemo.ui.text(placeholder输入标题), cimo.ui.slider(0, 100, value95, label置信度(%)), chartmo.ui.dropdown([line, bar, scatter], valueline), ) report.value # {title: ..., ci: 95, chart: line}借助 batch你可以把散落的多个控件封装为一个带语义标签的自定义组件在后续单元格中通过report.value一次性获取全部输入代码更紧凑、界面更整洁。七、补充API 速查成员类型/签名说明Html.batch(**elements)方法链式创建 batchmo.md/mo.html返回值均可调用mo.ui.batch(html, elements)类构造html: Htmlelements: Mapping[str, UIElement]on_changeCallable[[dict], None] \| None批值变化时的回调.valuedict[str, Any]各子元素当前值只读.elementsdict[str, UIElement]批内子元素克隆副本el[key]/el.get(key)索引按占位符名取子元素len(el)/iter(el)/in协议类 dict 访问结语mo.ui.batch是 marimo 中以模板为骨架、以控件为血肉的组合式交互方案Html.batch()链式调用简洁直观mo.ui.batch()直接实例化灵活可控value提供统一的字典化取值elements与类字典协议方便在代码中访问任意子元素on_change回调含嵌套场景保证与业务状态正确联动。配合str.format插值实现你可以在一个单元格内快速构建出贴合业务语义的自定义表单、范围选择器或配置面板。相关实现与测试可继续深入阅读 batch.py、hypertext.py、DictPlugin.tsx 与 test_batch.py。【免费下载链接】marimoA reactive notebook for Python — run reproducible experiments, query with SQL, execute as a script, deploy as an app, and version with git. Stored as pure Python. All in a modern, AI-native editor.项目地址: https://gitcode.com/GitHub_Trending/ma/marimo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考