gpt4 book ai didi

python - 如何在单独的文件中定义回调? (阴谋破折号)

转载 作者:行者123 更新时间:2023-12-03 13:52:51 25 4
gpt4 key购买 nike

背景

Dash Web 应用程序有一个 dash 应用程序实例,通常命名为 app ,并像这样启动:

app = dash.Dash(__name__)

然后,使用 callback 将回调添加到应用程序中。装饰师:
@app.callback(...)
def my_function(...):
# do stuff.

在您找到的大多数教程中,回调是使用 app.py 中的所有应用程序布局定义的。 .这当然只是 MWE 的做事方式。在实际应用程序中,将代码分离为模块和包将大大提高可读性和可维护性,但天真地将回调和布局分离只会导致循环导入。

问题

将回调和布局与 app.py 分开的正确方法是什么?在单页应用程序中?

MWE

这是一个有问题的最小(非)工作示例

文件结构
.
├── my_dash_app
│   ├── app.py
│   └── views
│   ├── first_view.py
│   └── __init__.py
└── setup.py

安装程序.py
import setuptools

setuptools.setup(
name='dash-minimal-realworld',
version='1.0.0',
install_requires=['dash>=1.12.0'],
packages=setuptools.find_packages(),
)

应用程序.py
import dash

from my_dash_app.views.first_view import make_layout

app = dash.Dash(__name__)
app.layout = make_layout()


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

first_view.py

from dash.dependencies import Input, Output

import dash_core_components as dcc
import dash_html_components as html

from my_dash_app.app import app

def make_layout():
return html.Div([
dcc.Input(id='my-id', value='initial value', type='text'),
html.Div(id='my-div')
])

@app.callback(Output(component_id='my-div', component_property='children'),
[Input(component_id='my-id', component_property='value')])
def update_output_div(input_value):
return 'You\'ve entered "{}"'.format(input_value)


运行 python ./my_dash_app/app.py导致循环依赖:
ImportError: cannot import name 'make_layout' from 'my_dash_app.views.first_view' (c:\tmp\dash_minimal_realworld\my_dash_app\views\first_view.py)

最佳答案

我不认为(但我可能是错的)本身有一个正确的方法,但是你可以做的是在你的启动代码 maindash.py 周围有一个中央模块( app = dash.Dash(__name__) ) , 并有不同的回调只需导入 app来自 my_dash_app.maindash .这将在它们自己的单独模块中设置回调,但将那个中央模块重新用于app。实例。

像这样显示它的概述是最简单的:
mwe
app.py作为启动一切的主要脚本。 maindash.py负责创建主应用程序实例。 first_view.py是定义装饰器以设置所有回调的地方。

结果如下:
enter image description here

.
├── my_dash_app
│ ├── app.py
│ ├── maindash.py
│ └── views
│ ├── first_view.py
│ └── __init__.py
└── setup.py

由于在 Python 中重复使用了导入,因此执行 from my_dash_app.maindash import app 并没有真正的危害。多次来自不同的其他模块,例如事件处理程序和主脚本。他们将共享同一个导入实例——因此重用 dash.Dash()实例也是如此。

只需确保在设置处理程序之前导入中央模块,就可以了。

这是为测试而分离的代码片段:

应用程序.py

from my_dash_app.maindash import app
from my_dash_app.views.first_view import make_layout

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

主破折号

import dash
app = dash.Dash(__name__)

first_view.py

from my_dash_app.maindash import app
from dash.dependencies import Input, Output

import dash_core_components as dcc
import dash_html_components as html

def make_layout():
return html.Div([
dcc.Input(id='my-id', value='initial value', type='text'),
html.Div(id='my-div')
])

@app.callback(Output(component_id='my-div', component_property='children'),
[Input(component_id='my-id', component_property='value')])
def update_output_div(input_value):
return 'You\'ve entered "{}"'.format(input_value)

关于python - 如何在单独的文件中定义回调? (阴谋破折号),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62102453/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com