You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 18:05:54