【Dash】回调函数专题

Callbacks专题

继初体验之后,这一部分是对应tutorial之后的回调专题。


高级特性

1.控制回调不更新-1

从doc中摘抄一句Callback functions: Python functions that are automatically called by Dash whenever an input component‘s property changes.
那如果想在特定的情况不进行更新,使用:from dash.exceptions import PreventUpdate

import dash
import dash_html_components as html
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate


external_stylesheets = [‘https://codepen.io/chriddyp/pen/bWLwgP.css‘]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)

app.layout = html.Div([
    html.Button(‘Click here to see the content‘, id=‘show-secret‘),
    html.Div(id=‘body-div‘)
])

@app.callback(
    Output(component_id=‘body-div‘, component_property=‘children‘),
    Input(component_id=‘show-secret‘, component_property=‘n_clicks‘)
)
def update_output(n_clicks):
    if (n_clicks is None) or (n_clicks % 2 == 0):  # 未点击或偶数不更新内容
        raise PreventUpdate
    else:
        return "So the n_clicks now is: {}.".format(str(n_clicks))

if __name__ == ‘__main__‘:
    app.run_server(debug=True)

得到:
【Dash】回调函数专题

初始时raise PreventUpdate,后续每次按键被点击次数到偶数次时,内容不更新。

2.控制回调不更新-2

在无需更新的output位置返回dash.no_update即可。


3.回调上下文信息

作用域为回调函数内部,通过dash.callback_context获取包含Input、State和Trigger信息记录,返回Json格式数据。

ctx = dash.callback_context
ctx_msg = json.dumps({
        ‘states‘: ctx.states,  # 这个看到的基本都是空
        ‘triggered‘: ctx.triggered,  # 最近一次的触发信息
        ‘inputs‘: ctx.inputs  # 历史输入信息记录
    }, indent=2)

4.revent_initial_call参数

先上官网Demo

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State


app = dash.Dash(__name__, suppress_callback_exceptions=True)
app.layout = html.Div([
    dcc.Location(id=‘url‘),
    html.Div(id=‘layout-div‘),
    html.Div(id=‘content‘)
])


@app.callback(Output(‘content‘, ‘children‘), Input(‘url‘, ‘pathname‘))
def display_page(pathname):
    return html.Div([
        dcc.Input(id=‘input‘, value=‘hello world‘),
        html.Div(id=‘output‘)
        ], style={‘background-color‘: ‘red‘}
    )

@app.callback(Output(‘output‘, ‘children‘), Input(‘input‘, ‘value‘), prevent_initial_call=True)
def update_output(value):
    print(‘>>> update_output‘)
    return value

@app.callback(Output(‘layout-div‘, ‘children‘), Input(‘input‘, ‘value‘), prevent_initial_call=True)
def update_layout_div(value):
    print(‘>>> update_layout_div‘)
    return value


if __name__ == ‘__main__‘:
    app.run_server(debug=True)

得到:

【Dash】回调函数专题

上面这个是初始时进入界面看到的,加了个颜色便于后期自己查看变化(看来自己真的不适合前端这些设计,尴尬??)

这个Demo想说明的是:prevent_initial_call方法在某些场合不适用。
对应到这个Demo中,可以看终端输出发现update_layout_div回调函数的执行不受影响,每次刷新页面都会执行。
原因如下:

【Dash】回调函数专题

具体可以替换掉suppress_callback_exceptions以及prevent_initial_call观察异常情况。
在这个demo中,app初始化时传递suppress_callback_exceptions=True是给禁止初始回调的函数假定一个输入input,若是去掉便会报错找不到id=input.


5.循环回调

体验一下官网Demo就能体会到 页面A组件与B组件之间相互作为输入输出同步更新 这一用法,在这里传入的属性是value.


写在后面,其实看到这里,就有些不想暂时把这个当作短期继续更新的方向了,更多的是前端的东西让我不习惯。
想到早期用Flask/Django弄的一些丑丑的Demo,笨拙,不堪回首。。。

2021.7.27 Dash部分先行停更(实际作图过程中,Tableau/PowerBI、有数BI、Python其他绘图库、Excel/PPT 足够)

参考资源

官网Advanced Callbacks章节

【Dash】回调函数专题

上一篇:使用 Swagger UI 与 Swashbuckle 创建 RESTful Web API 帮助文件(转)


下一篇:堆优化版的Dijkstra