如何构建类似Jupyter Notebook代码单元格的富输出及相关处理脚本?
构建Jupyter风格代码单元格富输出及相关脚本实现
一、理解Jupyter富输出的底层逻辑
Jupyter的富输出依赖IPython内核的display系统,它支持多种MIME类型输出(HTML、JSON、PNG、SVG等)。内核执行代码后,会把输出序列化为包含MIME类型的结构,前端再根据类型渲染对应的内容。
二、构建类似的富输出功能
核心是实现「后端捕获多类型输出+前端根据MIME类型渲染」的流程:
后端(Python)捕获富输出示例
借助IPython的内置API,可以直接复用Jupyter的输出捕获逻辑:
from IPython.core.interactiveshell import InteractiveShell # 初始化IPython shell实例 shell = InteractiveShell.instance() def run_code_get_rich_output(code): # 执行代码块 shell.run_cell(code) # 提取输出的多类型数据 output_list = [] for output in shell.last_execution_result.outputs: output_item = {} if 'text/plain' in output.data: output_item['plain_text'] = output.data['text/plain'] if 'text/html' in output.data: output_item['html'] = output.data['text/html'] if 'image/png' in output.data: output_item['png_base64'] = output.data['image/png'] output_list.append(output_item) return output_list # 测试代码 test_code = """ from IPython.display import HTML, Image display(HTML('<h4>这是HTML富输出</h4>')) display(Image(url='https://i.sstatic.net/1MgSx.png')) print('普通文本输出') """ rich_output = run_code_get_rich_output(test_code)
前端(JavaScript)渲染示例
拿到后端返回的输出数据后,根据类型渲染对应内容:
function renderOutput(outputList) { const container = document.getElementById('output-container'); outputList.forEach(item => { if (item.html) { const div = document.createElement('div'); div.innerHTML = item.html; container.appendChild(div); } if (item.png_base64) { const img = document.createElement('img'); img.src = `data:image/png;base64,${item.png_base64}`; container.appendChild(img); } if (item.plain_text) { const pre = document.createElement('pre'); pre.textContent = item.plain_text; container.appendChild(pre); } }); }
三、编写脚本生成Jupyter一致的富输出
如果要直接运行代码块并输出Jupyter风格结果,有两种可靠方式:
- 复用IPython内核:上面的Python示例就是这种方式,能完整复现Jupyter的所有富输出类型(包括交互式组件、图表等)。
- 遵循Jupyter格式规范:如果不需要完整内核,可自定义输出结构,严格匹配Jupyter
nbformat的输出格式(输出为包含data字段的字典,键为MIME类型)。
四、从ipynb文件提取输出部分
ipynb是JSON格式文件,直接解析JSON即可提取代码单元格的输出:
import json def extract_outputs_from_ipynb(file_path): with open(file_path, 'r', encoding='utf-8') as f: nb_json = json.load(f) result = [] for cell in nb_json['cells']: if cell['cell_type'] == 'code': # 提取单元格代码和对应输出 result.append({ 'code': ''.join(cell['source']), 'outputs': cell.get('outputs', []) }) return result # 提取示例 cell_outputs = extract_outputs_from_ipynb('your_notebook.ipynb') # 查看第一个代码单元格的输出 print(cell_outputs[0]['outputs'])
提取出的outputs结构和Jupyter内核返回的完全一致,直接用前端渲染逻辑就能展示成和原单元格相同的效果。
内容的提问来源于stack exchange,提问作者Julian Chu
相关产品推荐
相关产品推荐

