如何通过多按钮调用带参函数?ipywidgets仅最后一个按钮绑定生效问题
问题原因分析
这是Python中变量后期绑定导致的典型问题!
在你的循环里,每次创建的按钮都被赋值给同一个btn变量,当你给每个按钮绑定on_click(fn)时,回调函数fn并没有立刻捕获当前循环中btn的具体值,而是在按钮被点击的时候才会去查找btn这个变量的当前引用——而循环结束后,btn已经指向了最后一个创建的按钮,所以不管点哪个按钮,都会触发最后一个按钮的描述输出。
两种解决办法
方法1:用闭包捕获当前按钮
修改循环内的代码,通过闭包把每次循环的按钮对象固定下来:
import ipywidgets as widgets from IPython.core.display import display, HTML def fn(b): print(b.description+" clicked.") for i in range(10): btn= widgets.Button( description='Button '+str(i), disabled=False, button_style='info', tooltip='Delete' ) # 用闭包捕获当前的btn def create_callback(button): def callback(_): fn(button) return callback btn.on_click(create_callback(btn)) display(btn)
方法2:使用functools.partial绑定参数
借助functools.partial提前把每个按钮作为参数绑定到回调函数上:
import ipywidgets as widgets from IPython.core.display import display, HTML from functools import partial def fn(b): print(b.description+" clicked.") for i in range(10): btn= widgets.Button( description='Button '+str(i), disabled=False, button_style='info', tooltip='Delete' ) # 用partial绑定当前btn到fn上 btn.on_click(partial(fn, btn)) display(btn)
这样修改后,每个按钮点击时都会正确触发对应自身的回调逻辑,不会再只响应最后一个按钮啦!
内容的提问来源于stack exchange,提问作者Marcin Malinowski
相关产品推荐
相关产品推荐

