如何将Python动态计时结果作为HTML变量自动生成新报告
动态结果生成HTML报告实现方案
问题说明
现有每次运行输出结果均不固定的Python程序,需求为将所有运行结果汇总为HTML报告,且每次程序运行自动生成全新报告,示例代码与运行输出如下:
from time import time def f1(): for n in range(100): pass def f2(): n=0 while n<100: n+=1 if __name__ == "__main__": import timeit for i in range(5): a= timeit.timeit(f1, number=1000000) print(f'Time a {i+1}: {a: .3f} second(s)') for i in range(5): b= timeit.timeit(f2, number=1000000) print(f'Time b {i+1}: {b: .3f} second(s)')
示例运行输出:
Time a 1: 0.612 second(s) Time a 2: 0.618 second(s) Time a 3: 0.615 second(s) Time a 4: 0.615 second(s) Time a 5: 0.611 second(s) Time b 1: 2.189 second(s) Time b 2: 2.206 second(s) Time b 3: 2.374 second(s) Time b 4: 2.517 second(s) Time b 5: 2.494 second(s)
可选实现方案
根据报告复杂度需求,可以选择以下三类实现方式,核心逻辑一致:运行时先把动态结果收集到结构化变量(列表/字典)中,不要直接打印后丢弃,再将数据填充到预定义的HTML结构中,最后写入.html格式文件即可。每次程序运行重新走「收集数据-渲染内容-写入文件」流程,就会自动生成全新报告。需要保留历史报告就用时间戳作为文件名一部分,不需要保留历史就用固定文件名覆盖旧文件。
方案1:原生Python字符串拼接(轻量场景首选)
零第三方依赖,完全可控,适合结构简单的报告需求,改造示例如下:
from time import time import datetime def f1(): for n in range(100): pass def f2(): n=0 while n<100: n+=1 if __name__ == "__main__": import timeit # 收集结构化结果 results = {"f1": [], "f2": []} for i in range(5): a = timeit.timeit(f1, number=1000000) results["f1"].append(round(a, 3)) for i in range(5): b = timeit.timeit(f2, number=1000000) results["f2"].append(round(b, 3)) # 拼接HTML内容,可自定义样式 html_content = f""" <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>性能测试报告 {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</title> <style> .container {{ max-width: 900px; margin: 30px auto; font-family: system-ui, sans-serif; }} table {{ border-collapse: collapse; width: 100%; margin: 20px 0; }} th, td {{ border: 1px solid #eee; padding: 10px; text-align: center; }} th {{ background-color: #f5f5f5; }} .summary {{ margin: 20px 0; padding: 15px; background-color: #f0f9ff; border-radius: 4px; }} </style> </head> <body> <div class="container"> <h1>函数性能测试报告</h1> <p>生成时间:{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p> <div class="summary"> <p>f1 平均耗时:{sum(results['f1'])/len(results['f1']):.3f}s</p> <p>f2 平均耗时:{sum(results['f2'])/len(results['f2']):.3f}s</p> </div> <h2>详细测试结果</h2> <table> <tr> <th>测试轮次</th> <th>f1 耗时(s)</th> <th>f2 耗时(s)</th> </tr> {''.join([f'<tr><td>{i+1}</td><td>{results["f1"][i]}</td><td>{results["f2"][i]}</td></tr>' for i in range(5)])} </table> </div> </body> </html> """ # 写入文件 report_name = f"performance_report_{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}.html" with open(report_name, "w", encoding="utf-8") as f: f.write(html_content) print(f"报告已生成:{report_name}")
方案2:Jinja2模板引擎(复杂报告首选)
如果报告模块多、结构复杂,原生字符串拼接维护成本高,可以用Jinja2把HTML展示逻辑和Python业务逻辑分离,后续修改样式、调整结构不需要改动业务代码。
- 安装依赖:
pip install jinja2 - 单独编写HTML模板文件,用Jinja2语法标记动态内容占位符,支持在模板里写循环、判断逻辑
- 核心渲染代码:
from jinja2 import Environment, FileSystemLoader import datetime # 加载同目录下的模板文件 env = Environment(loader=FileSystemLoader('./')) template = env.get_template('report_template.html') # 传入收集到的结果渲染HTML html_out = template.render( generate_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'), results=results ) # 写入文件 with open("report.html", "w", encoding="utf-8") as f: f.write(html_out)
方案3:专用报告库(标准化场景首选)
如果是性能测试、数据分析类场景,不需要从零写HTML样式,可以直接用成熟库快速生成标准化报告:
- 测试类场景:配合测试框架使用pytest-html自动生成测试报告,性能对比类场景可以用perfplot直接导出性能对比HTML报告
- 数据分析类场景:用pandas的
to_html()方法直接把结构化数据表转为HTML表格,搭配少量样式即可快速生成报告 - 有可视化需求的场景,可以用pyecharts生成交互式图表,直接嵌入HTML报告中
内容的提问来源于stack exchange,提问作者DanielMateusz
相关产品推荐
相关产品推荐

