在进程中运行Dash服务器遇AttributeError:无法pickle本地lambda对象
解决进程中运行Dash服务器的Pickle报错问题
由于线程中停止Dash服务器无效,改用多进程运行时出现如下报错:
AttributeError: Can't pickle local object 'Flask.init.
. '
EOFError: Ran out of input
报错原因
Windows平台下,multiprocessing默认使用spawn模式启动子进程,该模式需要将父进程中的目标对象(此处为Test类实例的run_server方法)序列化传递给子进程。但Flask实例内部包含本地lambda函数(如默认错误处理回调),这类对象无法被Python的pickle机制序列化,导致进程启动失败。
解决方案
将Dash应用的初始化与启动逻辑完全放在子进程执行的函数中,避免父进程创建的Flask/Dash对象被序列化传递。修改后的代码如下:
import logging from dash import html, Dash from flask import Flask from multiprocessing import Process ############################## setup logger ############################# logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(threadName)s, %(levelname)s] %(message)s", handlers=[ logging.FileHandler("logs.log"), logging.StreamHandler() ] ) ######################################################################### def run_server(): # 子进程内独立创建Flask和Dash实例 flask_app = Flask(__name__) app = Dash(__name__, server=flask_app) # 定义页面布局 app.layout = html.Div(children=[ html.H1(children='Hello Dash'), html.P(children='This is a simple Dash app for testing.'), html.Button('Click Me', id='button') ]) logging.info("Starting Dash server") app.run_server(debug=True, use_reloader=False) class Test: def prepare_webserver(self): self.server_proc = Process(target=run_server, name='dash_server', daemon=True) self.server_proc.start() if __name__ == "__main__": sim_manager = Test() sim_manager.prepare_webserver()
原理说明
修改后,子进程启动时会直接执行run_server函数,在子进程内部独立创建Flask和Dash实例,无需序列化父进程中的任何对象,从根源上避免了pickle序列化失败的问题。如果后续需要父进程与子进程通信,可使用multiprocessing.Queue或Pipe,确保传递的对象均为可序列化类型。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

