如何将Python的print输出内容展示到Flask页面
实现Flask页面同步控制台print输出的三种方法
方法一:重定向标准输出到内存存储(非实时)
这种方法通过替换系统的stdout,把所有print的内容收集到内存列表中,页面刷新时展示最新内容,适合不需要实时更新的场景。
示例代码:
from flask import Flask, render_template_string import sys from io import StringIO app = Flask(__name__) # 存储所有print输出的列表 print_records = [] class CapturePrint(StringIO): def write(self, text): # 过滤空行,存入列表 cleaned_text = text.strip() if cleaned_text: print_records.append(cleaned_text) # 保留原控制台输出 super().write(text) # 替换系统标准输出 sys.stdout = CapturePrint() @app.route('/') def show_print(): # 测试print输出 print('Hello World!') print('这是一条测试打印内容') # 渲染页面展示收集到的内容 return render_template_string(''' <h2>控制台输出同步展示</h2> <pre style="background:#f5f5f5; padding:10px;"> {% for line in records %} {{ line }} {% endfor %} </pre> ''', records=print_records) if __name__ == '__main__': app.run(debug=True)
方法二:WebSocket实时推送(实时同步)
如果需要页面实时显示新的print内容,用WebSocket实现双向通信是最优方案,能让前端自动刷新输出。
首先安装依赖:
pip install flask-socketio
示例代码:
from flask import Flask, render_template_string from flask_socketio import SocketIO, emit import sys from threading import Lock import time app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' socketio = SocketIO(app, cors_allowed_origins="*") task_lock = Lock() # 自定义输出流,捕获print并推送到前端 class RealTimePrintStream: def write(self, text): cleaned_text = text.strip() if cleaned_text: # 推送内容到前端 socketio.emit('console_update', {'content': cleaned_text}) # 保留原控制台输出 sys.__stdout__.write(text) sys.stdout = RealTimePrintStream() @app.route('/') def index(): return render_template_string(''' <h2>实时控制台输出</h2> <pre id="console-area" style="background:#f5f5f5; padding:10px; height:300px; overflow:auto;"></pre> <script src="https://cdn.jsdelivr.net/npm/socket.io@4.6.0/dist/socket.io.min.js"></script> <script> const socket = io(); const consoleArea = document.getElementById('console-area'); socket.on('console_update', function(data) { consoleArea.textContent += data.content + '\\n'; // 自动滚动到底部 consoleArea.scrollTop = consoleArea.scrollHeight; }); </script> ''') # 模拟后台持续产生print输出 def background_job(): count = 1 while True: print(f'后台任务第 {count} 次输出') count += 1 time.sleep(2) # 客户端连接时启动后台任务(仅启动一次) @socketio.on('connect') def on_connect(): with task_lock: if not hasattr(background_job, 'started'): background_job.started = True socketio.start_background_task(target=background_job) if __name__ == '__main__': socketio.run(app, debug=True)
方法三:用日志模块替代print(生产环境推荐)
如果是生产环境,建议用logging模块替代print,配置多处理器让日志同时输出到控制台和前端页面,还能区分日志级别(INFO/WARNING/ERROR等)。
示例代码(结合WebSocket实时推送日志):
from flask import Flask, render_template_string from flask_socketio import SocketIO, emit import logging app = Flask(__name__) app.config['SECRET_KEY'] = 'your-secret-key' socketio = SocketIO(app, cors_allowed_origins="*") # 自定义日志处理器,推送日志到前端 class SocketLogHandler(logging.Handler): def emit(self, record): # 格式化日志内容 log_msg = f"{record.asctime} - {record.levelname} - {record.getMessage()}" socketio.emit('log_update', {'log': log_msg}) # 配置日志系统 logger = logging.getLogger() logger.setLevel(logging.INFO) # 添加控制台输出处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) logger.addHandler(console_handler) # 添加WebSocket推送处理器 socket_handler = SocketLogHandler() socket_handler.setFormatter(logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')) logger.addHandler(socket_handler) @app.route('/') def show_logs(): return render_template_string(''' <h2>实时日志输出</h2> <pre id="log-area" style="background:#f5f5f5; padding:10px; height:300px; overflow:auto;"></pre> <script src="https://cdn.jsdelivr.net/npm/socket.io@4.6.0/dist/socket.io.min.js"></script> <script> const socket = io(); const logArea = document.getElementById('log-area'); socket.on('log_update', function(data) { logArea.textContent += data.log + '\\n'; logArea.scrollTop = logArea.scrollHeight; }); </script> ''') # 测试日志输出 @app.route('/test-log') def test_log(): logger.info('这是一条普通信息日志') logger.warning('这是一条警告日志') logger.error('这是一条错误日志') return '日志已生成' if __name__ == '__main__': socketio.run(app, debug=True)
内容的提问来源于stack exchange,提问作者Singh
相关产品推荐
相关产品推荐

