python-3.x 通过Dash回调自定义装饰器

5cg8jx4n  于 2023-05-02  发布在  Python
关注(0)|答案(1)|浏览(197)

我试图了解是否有可能使用破折号回调与自定义装饰器。基本达世币应用程序:

from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv')

app = Dash(__name__)

app.layout = html.Div([
    html.H1(children='Title of Dash App', style={'textAlign':'center'}),
    dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
    dcc.Graph(id='graph-content')
])

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

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

我想用作装饰器的函数:

def my_decorator(func):
    def wrapper_function(*args, **kwargs):
        begin = time.time()
        func(*args,  **kwargs)
        end = time.time()
        print("Total time taken in : ", func.__name__, (end - begin))
    return wrapper_function

我试着做了以下几件事:

@my_decorator
@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

这个更新了 Jmeter 板,但没有打印总时间

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
@my_decorator
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

这一个打印时间,但 Jmeter 板不更新。
我需要 Jmeter 板更新和回调时间打印。Python似乎支持链式装饰器,但似乎不可能使用@callback。有办法吗?或者我应该复制/粘贴到每个函数?

euoag5mw

euoag5mw1#

问题是,在装饰器的内部函数(wrapper_function)中,没有返回装饰函数的结果。
由于没有显式返回,因此wrapper_function隐式返回None。实际上,您返回None作为输出Output('graph-content', 'figure'),因此您得到的是一个空的数字。
在第二次回调尝试中,如果查看浏览器的网络选项卡,您可以看到正在发生这种情况。时间打印在控制台中,并向_dash-update-component发出请求,以便执行两个函数。
您可以将结果存储在一个变量中,并在打印所花费的时间后返回它:

def my_decorator(func):
    def wrapper_function(*args, **kwargs):
        begin = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print("Total time taken in : ", func.__name__, (end - begin))
        return result
    return wrapper_function

现在这个工作:

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
@my_decorator
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

相关问题