• Dash 2.9.0版本重磅新功能一览


    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/dash-master

      大家好我是费老师,就在昨晚,Dash框架发布了其2.9.0版本更新,在一众更新内容中,有两条新特性在我看来尤为重要,可以大幅度提升我们开发Dash应用的效率,下面我就将带大家一起了解它们的具体内容:

    1 允许多个回调函数重复Output#

      在之前版本的Dash中,严格限制了不同的回调函数不可以对相同的id.属性目标进行输出,以下面的示例应用为例:

    import dash
    from dash import html
    import feffery_antd_components as fac
    from dash.dependencies import Input, Output
    
    app = dash.Dash(__name__)
    
    app.layout = html.Div(
        [
            fac.AntdSpace(
                [
                    fac.AntdButton(
                        '按钮1',
                        id='button-demo1'
                    ),
                    fac.AntdButton(
                        '按钮2',
                        id='button-demo2'
                    )
                ]
            ),
            fac.AntdParagraph(
                id='output-demo'
            )
        ],
        style={
            'padding': '50px 100px'
        }
    )
    
    
    @app.callback(
        Output('output-demo', 'children'),
        Input('button-demo1', 'nClicks'),
        prevent_initial_call=True
    )
    def trigger1(nClicks):
    
        return f'按钮1: {nClicks}'
    
    
    @app.callback(
        Output('output-demo', 'children'),
        Input('button-demo2', 'nClicks'),
        prevent_initial_call=True
    )
    def trigger2(nClicks):
    
        return f'按钮2: {nClicks}'
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    

      如果我们希望两个AntdButton分别点击后,可以通过两个不同的回调函数对同一AntdPargraph的内容进行输出,在之前的版本中默认会报下图所示的Duplicate callback outputs错误:

      在之前的版本中遇到这种情况解决方式也有很多,常用的如将多个回调函数整合为一个并在回调函数中,再基于dash.ctx.triggered_id判断每次回调函数究竟是由哪个Input触发的,这在较复杂回调功能的编写中就不太方便了。

      而从Dash 2.9.0版本开始,为Output()引入了bool型新参数allow_duplicate,默认为False,当设置为True后,当前Output便可以允许通过多个回调函数共同输出,将上面的例子回调部分进行改造,对后续重复的Output设置allow_duplicate=True

    @app.callback(
        Output('output-demo', 'children', allow_duplicate=True),
        Input('button-demo2', 'nClicks'),
        prevent_initial_call=True
    )
    def trigger2(nClicks):
    
        return f'按钮2: {nClicks}'
    

      就可以不受限制啦~

      当然,虽然有了这个新特性帮助我们解除了不少限制,但是我的建议还是不要滥用,它不一定可以使得我们的代码更简洁,基于dash.ctx.triggered_id的分支判断在很多场景下还是更合适。

      作为一个新的功能,allow_duplicate目前在常规的服务端回调函数中运作正常,但在浏览器端回调函数中暂时无法使用,静待后续Dash官方的更新。

    2 新增Patch()操作模式#

      Dash 2.9.0版本中新增参数局部快捷更新操作Patch(),使得我们可以在回调函数中对目标属性进行局部更新,这样说起来还是比较抽象,我们举例说明:

      假如我们的应用中要实现这样的交互逻辑:每点击一次AntdButton,就会在下方AntdSpace中新增一行文字内容,在以前的版本中,要实现这个功能,我们需要在回调函数中额外将目标AntdSpacechildren属性作为State传入,从而在每次回调执行时,将新的一行内容追加到先前状态的children列表中,再进行输出:

    import dash
    import uuid
    from dash import html
    import feffery_antd_components as fac
    from dash.dependencies import Input, Output, State
    
    app = dash.Dash(__name__)
    
    app.layout = html.Div(
        [
            fac.AntdButton(
                '新增一行',
                id='add-new-line'
            ),
            fac.AntdSpace(
                [],
                id='target-container',
                direction='vertical',
                style={
                    'width': '100%'
                }
            )
        ],
        style={
            'padding': '50px 100px'
        }
    )
    
    
    @app.callback(
        Output('target-container', 'children'),
        Input('add-new-line', 'nClicks'),
        State('target-container', 'children'),
        prevent_initial_call=True
    )
    def add_new_line(nClicks, origin_children):
    
        return [
            *origin_children,
            str(uuid.uuid4())
        ]
    
    
    if __name__ == '__main__':
        app.run(debug=True)
    
    

      这样做的弊端很明显——我们每次更新都需要先取回目标属性的现有状态,这带来了多余的资源消耗,而有了Patch()模式,我们就可以将回调函数改写为下面的形式,实现相同的效果:

    @app.callback(
        Output('target-container', 'children'),
        Input('add-new-line', 'nClicks'),
        prevent_initial_call=True
    )
    def add_new_line(nClicks):
    
        patch = dash.Patch()
        patch.append(str(uuid.uuid4()))
    
        return patch
    

      相当于在回调函数中通过实例化Patch,创建了针对目标Output的远程代理对象,在回调函数中针对该代理对象的各种常用操作,都会在回调函数执行后落实到用户浏览器中的目标属性上,这听起来可能有些抽象,我用下面的例子展示了基于Patch可以实现的常用局部值操作(对应代码受篇幅限制,请在文章开头的github仓库中查看):


      以上就是本文的全部内容,对Dash应用开发感兴趣的朋友,欢迎添加微信号CNFeffery,备注“dash学习”加入我的技术交流群,一起成长一起进步。

      

      

  • 相关阅读:
    CDH大数据平台 SSLError: sslv3 alert bad certificate
    CF1535F String Distance
    JSP response对象:响应客户端的请求并向客户端输出信息
    Qt/C++ 加入轻便性能收集器
    Nginx:过滤模块的实现
    性能测试-基础理论知识
    Linux基础(三)----->权限理解和文件属性
    java计算机毕业设计ssm高校工资管理系统
    Spring依赖注入源码解析(上)
    现货白银需要注意八大事项
  • 原文地址:https://www.cnblogs.com/feffery/p/17227380.html