如何在Dash标签页展示Python脚本?含代码报错修复问询
Dash展示多脚本标签页的报错修复方案
问题背景
- 需求:在Dash中用标签页展示多个.py文件,每个脚本对应一个标签页
- 困境:脚本过长,逐行编写或截图展示都不现实
- 已尝试的无效方案:
- 用
html.P打印脚本,丢失换行格式 - 转为HTML后Dash无法直接解析
convert-html-to-dash库无法正常使用- 转JSON作为图表展示行不通
- 用
当前报错
运行HTML转Dash组件的代码时,出现错误:
AttributeError: 'cython_function_or_method' object has no attribute 'fromstring'
提供的错误代码
import ast def convert_html_to_dash(html_code, dash_modules=None): """Convert standard html (as string) to Dash components. Looks into the list of dash_modules to find the right component (default to [html, dcc, dbc]).""" from lxml.etree import ElementTree if dash_modules is None: from dash import html from dash import dcc dash_modules = [html, dcc] try: import dash_bootstrap_components as dbc dash_modules.append(dbc) except ImportError: pass def find_component(name): for module in dash_modules: try: return getattr(module, name) except AttributeError: pass raise AttributeError(f"Could not find a dash widget for '{name}'") def parse_css(css): """Convert a style in ccs format to dictionary accepted by Dash""" return {k: v for style in css.strip(";") split(";") for k, v in [style.split(":")]} def parse_value(v): try: return ast.literal_eval(v) except (SyntaxError, ValueError): return v parsers = {"style": parse_css, "id": lambda x: x} def _convert(elem): comp = find_component(elem.tag.capitalize()) children = [_convert(child) for child in elem] if not children: children = elem.text attribs = elem.attrib.copy() if "class" in attribs: attribs["className"] = attribs.pop("class") attribs = {k: parsers.get(k, parse_value)(v) for k, v in attribs.items()} return comp(children=children, **attribs) et = ElementTree.fromstring(html_code) return _convert(et) file1 = open('exits.txt', 'r') file2 = open('exits_dash.py', 'w') count = 0 for line in file1: count += 1 line_out = convert_html_to_dash(line) file2.writelines(line) file1.close() file2.close()
修复步骤
1. 修正ElementTree调用错误
ElementTree.fromstring是错误的调用方式,fromstring是lxml.etree下的独立函数,不是ElementTree类的方法。修改导入和解析代码:
# 替换原导入语句 from lxml.etree import fromstring # 替换解析行 et = fromstring(html_code)
2. 修复parse_css函数的语法与逻辑错误
原代码存在语法缺失(缺少点号),且未处理空样式条目,修改后:
def parse_css(css): """Convert a style in css format to dictionary accepted by Dash""" style_dict = {} for style in css.strip(";").split(";"): if style: # 跳过分割后产生的空字符串 # 只分割一次,避免样式值中包含冒号导致错误 key, value = style.split(":", 1) style_dict[key.strip()] = value.strip() return style_dict
3. 修正文件处理逻辑
原代码逐行转换HTML(单条行不是完整HTML元素,会导致解析失败),且写入原行毫无意义,改为读取完整HTML内容并生成可执行的Dash组件代码:
# 替换原文件处理代码 with open('exits.txt', 'r', encoding='utf-8') as file1, open('exits_dash.py', 'w', encoding='utf-8') as file2: # 读取完整的HTML内容 full_html = file1.read() # 转换为Dash组件 dash_comp = convert_html_to_dash(full_html) # 写入导入语句和组件代码 file2.write("from dash import html, dcc\n") try: file2.write("import dash_bootstrap_components as dbc\n\n") except ImportError: file2.write("\n") file2.write(f"generated_component = {repr(dash_comp)}")
4. 更优方案:直接展示代码内容
如果你的核心需求只是展示.py文件的代码,完全不需要转HTML再转Dash组件,用html.Pre组件可以直接保留代码的换行和格式,示例代码:
from dash import Dash, html, dcc app = Dash(__name__) # 读取脚本内容的工具函数 def get_script_content(file_path): with open(file_path, 'r', encoding='utf-8') as f: return f.read() app.layout = html.Div([ dcc.Tabs([ dcc.Tab( label="脚本1", children=[html.Pre( get_script_content("script1.py"), style={"whiteSpace": "pre-wrap", "padding": "20px", "background": "#f5f5f5"} )] ), dcc.Tab( label="脚本2", children=[html.Pre( get_script_content("script2.py"), style={"whiteSpace": "pre-wrap", "padding": "20px", "background": "#f5f5f5"} )] ) ]) ]) if __name__ == "__main__": app.run_server(debug=True)
内容的提问来源于stack exchange,提问作者kqd
相关产品推荐
相关产品推荐

