本文示例代码已上传至我的
Github
仓库:https://github.com/CNFeffery/dash-masterGitee同步仓库地址:https://gitee.com/cnfeffery/dash-master
大家好我是费老师,几个小时前Dash
发布了其2.18.0
版本,执行下面的命令进行最新版本Dash
的安装:
bash
pip install dash -U
2.18
版本中新增了多项重要的新功能,使得我们在开发Dash
应用功能时更加的得心应手,下面我们就来一起get其中的重点😉:
1 新增全局/局部回调函数错误处理机制
从2.18
版本开始,Dash
新增了针对回调函数的全局/局部错误处理机制,使得我们可以通过自定义的错误处理函数,来更统一便捷的处理回调函数计算逻辑中抛出的错误。
1.1 全局错误处理
针对全局错误处理 ,我们可以编写自定义函数,其第一个输入参数 接收每次抛出的错误,接着将此函数赋值给dash.Dash()
中的on_error
参数即可。
举个简单的例子(对应本文源码app1.py
),下面的代码中我们定义了函数handle_global_error()
,在其内部基于Dash
中的服务端set_props()
,将每次错误发生对应的错误触发来源 、错误信息 以fac
中全局提示的形式展示在网页中:
python
import dash
from dash import html, set_props
import feffery_antd_components as fac
from dash.dependencies import Input, Output
from feffery_dash_utils.style_utils import style
def handle_global_error(e):
# 利用服务端set_props()将错误信息集中抛出
set_props(
"error-message",
{
"children": fac.AntdMessage(
content="触发id {},错误信息 {}".format(dash.ctx.triggered_id, e),
type="error",
)
},
)
app = dash.Dash(__name__, on_error=handle_global_error)
应用页面内容代码如下,我们定义了两组按钮及对应的输出目标:
python
app.layout = html.Div(
[
# 错误消息统一更新目标
fac.Fragment(id="error-message"),
fac.AntdSpace(
[
fac.AntdSpace(
[
fac.AntdButton("全局错误示例1", id="trigger-global-error1"),
fac.AntdText(id="trigger-global-error-output1"),
]
),
fac.AntdSpace(
[
fac.AntdButton("全局错误示例2", id="trigger-global-error2"),
fac.AntdText(id="trigger-global-error-output2"),
]
),
],
direction="vertical",
style=style(width="100%"),
),
],
style=style(padding=100),
)
回调函数部分,我们则针对两组不同的"输入-输出"关系,分别在按钮累计点击次数nClicks
为偶数时,抛出不同的错误:
python
@app.callback(
Output("trigger-global-error-output1", "children"),
Input("trigger-global-error1", "nClicks"),
prevent_initial_call=True,
)
def global_error_demo1(nClicks):
"""示例回调函数1"""
if nClicks % 2 == 0:
# 触发示例错误
1 / 0
return f"nClicks: {nClicks}"
@app.callback(
Output("trigger-global-error-output2", "children"),
Input("trigger-global-error2", "nClicks"),
prevent_initial_call=True,
)
def global_error_demo2(nClicks):
"""示例回调函数2"""
if nClicks % 2 == 0:
# 触发示例错误
raise Exception("这是一个自定义错误")
return f"nClicks: {nClicks}"
应用操作演示如下,可以看到所有的错误都被全局错误处理函数捕获并进行集中处理😉:
1.2 局部错误处理
与上文中介绍的全局错误处理 写法不同,当我们希望将自定义的错误处理函数专门 作用于某个或某些 回调函数时,可以在对应回调函数的app.callback()
中将自定义函数赋值给同名的on_error
参数,我们在前面示例的基础上进行改造(对应本文源码app2.py
),额外定义了错误处理函数handle_local_error
,并赋值给对应回调函数的on_error
参数,对应代码片段如下:
python
def handle_local_error(e):
# 利用服务端set_props()将错误信息集中抛出
set_props(
"error-message",
{
"children": fac.AntdMessage(
content="🧐异常发生,异常信息 {}".format(e),
type="error",
)
},
)
@app.callback(
Output("trigger-global-error-output2", "children"),
Input("trigger-global-error2", "nClicks"),
on_error=handle_local_error,
prevent_initial_call=True,
)
def global_error_demo2(nClicks):
"""示例回调函数2"""
if nClicks % 2 == 0:
# 触发示例错误
raise Exception("这是一个自定义错误")
return f"nClicks: {nClicks}"
应用操作效果如下,可以看到通过设置on_error=handle_local_error
,我们成功的改变了回调函数global_error_demo2
的错误处理过程:
大家可以在日常Dash
应用开发的过程中,妥善使用这套机制,使得我们的应用功能更稳健😎~
2 浏览器端回调上下文补充outputs_list
新版本为浏览器端回调 函数中可以调用的上下文对象window.dash_clientside.callback_context
补充了outputs_list
属性,可以在一些特殊的场景下,在计算逻辑中取得此属性辅助计算。
举个简单的例子,下面我们构造了10组开关 和输入框 ,每个开关的勾选可以控制对应输入框的禁用状态,且同时最多禁用3组,操作演示效果如下:
具体回调逻辑见文章开头地址中的源码app3.py
,借助上下文中的outputs_list
,实现了更具针对性的高效回调更新。
除此之外,还针对动态回调函数 增加了动态依赖库加载等新特性,并修复了若干小问题,完整的更新内容说明请移步https://github.com/plotly/dash/releases/tag/v2.18.0
。
以上就是本文的全部内容,对Dash
应用开发感兴趣的朋友,欢迎添加微信号CNFeffery
,备注"dash学习"加入我们的技术交流群,一起成长一起进步。