资讯详情

marimo 响应式多选组件 `mo.ui.multiselect` 完全指南:从基础用法到源码级参数解析

📅 2026/9/13 14:49:35 | 华诺云谱 👁 阅读
marimo 响应式多选组件 `mo.ui.multiselect` 完全指南:从基础用法到源码级参数解析
marimo 响应式多选组件mo.ui.multiselect完全指南从基础用法到源码级参数解析【免费下载链接】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/marimomo.ui.multiselect是 marimo 响应式笔记本reactive notebook内置的多选输入组件允许用户在预定义的选项中勾选任意多个值并将选择结果以响应式变量的形式自动驱动下游单元格重新执行。本文以官方 API 文档 docs/api/inputs/multiselect.md 为核心骨架结合后端实现marimo/_plugins/ui/_impl/input.py、前端渲染插件frontend/src/plugins/impl/MultiselectPlugin.tsx与单元测试tests/_plugins/ui/_impl/test_input.py完整讲解其参数、返回值语义、选项映射规则、数据框联动与边界行为帮助你写出可复现、可交互的多选数据应用。一、快速上手文档中的最小示例官方文档docs/api/inputs/multiselect.md给出的核心示例非常精炼——创建三个水果选项并把选中结果实时展示出来import marimo as mo app.cell def __(): options [Apples, Oranges, Pears] multiselect mo.ui.multiselect(optionsoptions) return app.cell def __(): mo.hstack([multiselect, mo.md(fHas value: {multiselect.value})]) return这里有两个关键点组件即变量multiselect既是要渲染在页面上的 UI 元素也是一个响应式值容器。任何引用了multiselect.value的单元格都会在用户勾选/取消选项后自动重新执行无需手动触发。渲染与取值的分离组件对象本身出现在单元格末尾时会被渲染为交互控件而.value才是业务上可用的数据。上面示例用mo.hstack把控件与展示文本水平排列实时反映当前选中项。在仓库的完整示例 examples/ui/multiselect.py 中可以看到同样的模式被组织成正式的多单元格笔记本__generated_with 0.19.7其中multiselect.value单独放在一个单元格里供下游引用。二、完整参数参考继承自类文档的签名multiselect类的完整签名定义在 marimo/_plugins/ui/_impl/input.py其类型标注为UIElement[list[str], list[object]]——即前端交互层使用字符串键后端业务层返回原始对象列表。参数如下参数类型默认值说明optionsSequence[Any] \| dict[str, Any]必填选项集合见下文「选项的两种写法」valueSequence[Any]None初始选中的选项列表未指定时为空列表[]labelstr组件的 Markdown 标签支持富文本on_changeCallable[[list[object]], None]None值变化时的回调函数接收选中值列表full_widthboolFalse是否占满容器宽度max_selectionsintNone最大可选数量None表示不限disabledboolFalse是否禁用组件与公开属性对应value: list[object]——当前选中的值列表注意不是显示名而是映射后的原始值未选择任何项时为空列表[]。options: dict[str, Any]——显示名 → 真实值的映射字典这是理解整个组件行为的关键。从源码可见初始化时会把这些参数序列化为前端插件的argsoptions键列表、full-width、max-selections、disabled组件名固定为marimo-multiselect对应前端插件注册的tagName见 frontend/src/plugins/impl/MultiselectPlugin.tsx。三、选项的两种写法序列与字典3.1 序列写法列表/元组ms mo.ui.multiselect(options[Apples, Oranges, Pears])此时显示名与值完全一致options属性等价于{Apples: Apples, Oranges: Oranges, Pears: Pears}value返回的是字符串列表。3.2 字典写法显示名与值分离ms mo.ui.multiselect( options{Apples: 1, Oranges: 2, Bananas: 3}, value[Apples], ) assert ms.value [1] # 返回的是映射后的真实值当需要界面显示友好的名称、代码里使用紧凑的 ID/数值时字典写法是标准解法。测试 tests/_plugins/ui/_impl/test_input.py 验证了这一点选中Apples时value返回[1]全选后返回[1, 2, 3]。3.3 底层实现选项映射的构建源码揭示了序列到字典的转换逻辑input.py 的_build_option_map遍历每个选项用_to_option_name生成显示名见下节若两个选项映射出相同显示名立即抛出ValueError(Duplicate option name ...)避免选项被静默覆盖在构建过程中同步完成去重校验保证单次遍历即可完成对生成器等一次性可迭代对象友好。当传入显式字典时字典本身按键去重因此不会触发该校验测试 test_input.py 确认了该行为。四、非字符串选项显示名与真实值如何对应options支持任意类型的元素但 UI 层只能展示字符串。源码中的_to_option_nameinput.py定义了转换规则字符串选项原样作为显示名其他类型int、float、bool、元组、自定义对象等使用repr(option)生成显示名。测试 test_multiselect_non_string_options 完整覆盖了这些情形# 整数选项 ms mo.ui.multiselect(options[1, 2, 3]) assert ms.options {1: 1, 2: 2, 3: 3} ms._update([1]) # 选中显示名 1 assert ms.value [1] # 得到真实值 1 # 浮点、布尔 mo.ui.multiselect(options[1.0, 2.0], value[1.0]) mo.ui.multiselect(options[True, False], value[True]) # 自定义对象按 repr 匹配 class SomeObject: ... ms mo.ui.multiselect(options[SomeObject(a1), SomeObject(a2)], value[SomeObject(a1)]) assert ms.value [SomeObject(a1)] # 混合类型 ms mo.ui.multiselect(options[1, 2, (3, 4)], value[1]) assert ms.options {1: 1, 2: 2, (3, 4): (3, 4)}与之配套的_validate_option_nameinput.py会在值转换时校验显示名是否合法若传入的键不在options中抛出带完整候选列表的错误信息。例如value[4]但选项只有[1,2,3]时错误消息为The option name 4 is not a valid option. Please use one of the following options: [1, 2, 3]见 test_multiselect_invalid_value。注意_MAX_OPTIONS上限单组件最多支持 100000 个选项multiselect._MAX_OPTIONS: Final[int] 100000input.py。超过该数量会抛出ValueError并建议改用mo.ui.text()让用户输入选项名、或使用mo.ui.table()展示匹配结果测试用 20 万个选项验证了该限制见 test_multiselect_too_many_options。五、高级参数实战初始值、上限、禁用与回调5.1 初始选中值valuems mo.ui.multiselect( options[Apples, Oranges, Pears], value[Apples, Pears], # 打开页面即默认选中两项 )value接收的应是显示名序列在构造时若传入非字典选项每个值都会经过_to_option_name归一化为显示名input.py因此直接传原始对象如value[1.0]也能正确匹配。5.2 最大可选数量max_selectionsms mo.ui.multiselect(options[Apples, Oranges, Pears], max_selections2)源码在构造阶段做了两处严格校验input.pymax_selections 0时抛出ValueError(max_selections cannot be less than 0.)初始选中数超过上限时抛出ValueError(Initial value cannot be greater than max_selections.)。对应测试见 test_multiselect。该参数在前端会透传给SelectList的maxSelections超出后 UI 层禁止继续勾选MultiselectPlugin.tsx。5.3 禁用与全宽布局mo.ui.multiselect(options[a, b, c], disabledTrue) # 只读 mo.ui.multiselect(options[a, b, c], full_widthTrue) # 撑满容器测试确认disabled会原样写入前端组件参数test_multiselect_disabledfull_width同时影响控件与 label 的布局宽度。5.4 变化回调on_changedef handle_change(values: list[object]) - None: print(now selected:, values) mo.ui.multiselect(options[a, b, c], on_changehandle_change)回调在每次值变化时触发接收映射后的真实值列表。回调适合执行日志、副作用等操作而响应式下游单元格则应直接读取multiselect.value。六、数据框联动from_series一行生成多选当需要根据某列数据的唯一值生成多选过滤条件时multiselect.from_series是最实用的入口input.pyimport pandas as pd df pd.DataFrame({A: [a, b, c]}) ms mo.ui.multiselect.from_series(df[A], value[b]) # 等价于 # ms mo.ui.multiselect(options[a, b, c], labelA, value[b])其底层调用 marimo/_data/series.py 的get_category_series_info剔除空值drop_nulls()后取列的唯一值并排序生成categories列名作为默认label得益于 Narwhals 的nw.narwhalify装饰该函数对 pandas、Polars、PyArrow 等数据框库统一生效。因此from_series可以直接接收任意支持的数据框列。测试 test_multiselect_from_series_non_string 还验证了非字符串列如整数列也能正确映射value[2]得到ms.value [2]。通过kwargs仍可覆盖options与label并传入max_selections等其余参数。七、前端渲染与交互细节后端序列化的组件参数由前端插件接收并渲染frontend/src/plugins/impl/MultiselectPlugin.tsxtagName marimo-multiselect与后端_name一一对应Zod 校验器定义了initialValue字符串数组、label、options字符串数组、fullWidth、maxSelections、disabled六个字段实际渲染使用SelectList组件开启multiple{true}、pinSelected{true}选中项置顶/固定显示与compactChipTrigger{true}紧凑的标签触发器样式。因此浏览器端的交互数据流是用户勾选 → 前端以显示名字符串数组回传 → 后端_convert_valueinput.py逐一校验显示名并映射为真实对象列表 → 更新multiselect.value→ 触发引用该值的单元格重新执行。八、常见错误速查均有测试佐证场景错误信息节选测试位置序列选项显示名重复如[a, a]或[1, 1]Duplicate option name a ...test_input.py选项数超过 100000The maximum number of options allowed is 100000 ...test_input.pymax_selections为负数max_selections cannot be less than 0.test_input.py初始选中数超过max_selectionsInitial value cannot be greater than max_selections.test_input.pyvalue包含不存在的选项名The option name 4 is not a valid option. Please use one of ...test_input.py九、实战组合多选过滤数据表把前面所有能力串起来一个典型的多选筛选场景如下mo.ui.table与mo.ui.multiselect组合import marimo as mo import pandas as pd df pd.DataFrame({ category: [fruit, fruit, vegetable, vegetable, grain], item: [apple, orange, carrot, broccoli, rice], }) categories mo.ui.multiselect.from_series(df[category]) filtered df[df[category].isin(categories.value)] mo.hstack([categories, mo.md(fFiltered to {len(filtered)} rows)]) mo.ui.table(filtered)选中categories中的分类时filtered与表格单元格会自动重算取消全部勾选时value为[]此时isin([])会过滤出空表——如需全选即不过滤的语义可自行判断if categories.value。这类响应式数据流正是 marimo 笔记本的核心使用方式更多交互模式可参考 docs/api/inputs/index.md 与 examples/ui/multiselect.py。小结mo.ui.multiselect是一个小而全的响应式多选组件序列/字典两种选项写法满足了简单列表与显示名-值分离两类需求repr映射规则让任意 Python 对象都可作为选项from_series打通了数据框列的快捷生成而max_selections、disabled、on_change等参数覆盖了绝大多数表单场景。理解其options字典与value映射的底层语义见 input.py你就能在任何 marimo 笔记本中写出数据驱动、可复现的多选交互界面。【免费下载链接】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),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。