You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jupyter Widgets嵌入包装函数后无法获取用户选中值的求助

问题解决:Jupyter Widgets嵌套函数中返回默认值的问题

首先纠正代码笔误

你的get_choices函数最后返回的是未定义的wiki_edges_select,这是拼写错误,应该返回函数内创建的selections列表,这是基础问题。

核心原因分析

你遇到的问题本质是:直接返回Widget对象时,在嵌套函数的局部作用域中,Widget的状态同步存在延迟或作用域问题。当用input()阻塞等待时,单独调用时choices是全局变量,Widget实例会被保留,打印时能正确显示更新后的状态;但在包装函数中,choices是局部变量,函数执行完毕后Widget实例可能被回收,导致打印时显示初始默认值。

解决方案

方案1:返回选中值而非Widget对象

修改get_choices函数,直接返回每个ToggleButtons的value属性(即用户选中的内容),而非Widget实例本身。这样无论是否嵌套,都能直接拿到实际选中值:

import ipywidgets as widgets
from IPython.display import display

def get_choices():    
    selections = [
        widgets.ToggleButtons(
            options=['Not Included', 'Included', 'Favorite'],
            description=f"{choice}",
            disabled=False,
            style={'description_width': '300px'}
        )
        for choice in ['choice1', 'choice2', 'choice3']
    ]
    
    for e in selections:
        display(e)

    print("\n\nPRESS ENTER WHEN FINISHED")
    input()
    
    # 返回用户选中的实际值,而非Widget对象
    return [sel.value for sel in selections]

# 单独调用测试
choices = get_choices()
print(choices)
# 输出示例:['Included', 'Included', 'Favorite']

# 包装函数调用测试
def get_choices_and_process():
    choices = get_choices()
    print(choices)

get_choices_and_process()
# 输出示例:['Included', 'Included', 'Favorite']

方案2:用按钮触发选择完成(推荐)

input()是同步阻塞方式,在Jupyter环境中可能导致Widget状态同步不及时。更可靠的方式是使用按钮控件触发状态获取,避免阻塞事件循环:

import ipywidgets as widgets
from IPython.display import display

def get_choices():    
    selections = [
        widgets.ToggleButtons(
            options=['Not Included', 'Included', 'Favorite'],
            description=f"{choice}",
            disabled=False,
            style={'description_width': '300px'}
        )
        for choice in ['choice1', 'choice2', 'choice3']
    ]
    
    finish_btn = widgets.Button(description="完成选择")
    output = widgets.Output()
    result = None

    def on_finish_clicked(b):
        nonlocal result
        result = [sel.value for sel in selections]
        with output:
            print("选择已完成!")
        finish_btn.disabled = True

    finish_btn.on_click(on_finish_clicked)

    # 显示所有控件
    for e in selections:
        display(e)
    display(finish_btn)
    display(output)

    # 等待用户点击按钮获取结果
    while result is None:
        pass

    return result

def get_choices_and_process():
    choices = get_choices()
    print(choices)

get_choices_and_process()

说明

方案1简单直接,适合快速修改;方案2更符合Jupyter Widget的异步交互模式,避免阻塞问题,体验更流畅。

内容的提问来源于stack exchange,提问作者Fortunato

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 11:26:12