写了一个在线执行python的小工具,实现手机编写python代码后运行。
为了初学者验证一些简单的python代码,写了一个小程序,能在线运行一些基础的python代码,还给了一些例子,后续会新增更多用例。

简单首页

后续更新其他基础知识

在线编程页面里主要是一个输入框,和一些代码例子,点击即可自动导入,点击运行代码后, 后端会执行相应运行。


运行结果页面里,有详细的运行print打印结果 和 运行代码,可一键复制
后端核心代码如下:
import io
import sys
from flask import g
import random
from common.dbTools.paging import easy_paging
from models.code import XExampleCode
from common.resMsg import ok_res
def run():
data = g.jm
code_str = data.get('code')
res = capture_print_output(code_str)
res_data = {
'code': code_str,
'res': res
}
return ok_res(res_data)
def capture_print_output(code_str):
# 创建一个StringIO对象来捕获输出
captured_output = io.StringIO()
# 将标准输出重定向到StringIO对象
sys.stdout = captured_output
try:
# 执行传入的Python代码
exec(code_str)
except Exception as e:
return [f"Error: {str(e)}"]
finally:
# 恢复标准输出
sys.stdout = sys.__stdout__
# 返回捕获的输出并按行分割成列表
return captured_output.getvalue().splitlines()
代码详细解释
由chatGPT协助整理
这个代码实现了一个通过 Flask 路由执行动态传入 Python 代码的功能,并捕获其中的 print 输出。以下是对代码的逐步解析。
1. 导入模块
import io
import sys
from flask import g
import random
from common.dbTools.paging import easy_paging
from models.code import XExampleCode
from common.resMsg import ok_res
io:用于处理文本流,包括字符串流。这里用它来捕获标准输出(stdout)。sys:提供访问和修改 Python 解释器的接口。这里用来重定向标准输出。flask.g:Flask 中的全局变量 g,用于存储当前请求的上下文数据。在此代码中,它用来获取请求数据 g.jm。random:标准 Python 库,用于生成随机数(虽然在当前代码中没有用到)。easy_paging:自定义的分页工具模块,可能是用于实现分页功能的工具函数(当前代码中没有使用)。XExampleCode:假设是你定义的模型类(此代码中未使用,但可能在其他地方使用)。ok_res:从 common.resMsg 模块导入的函数,显然是一个标准的返回响应函数,用来封装返回的结果。2. run 函数:接收输入代码并返回执行结果
def run():
data = g.jm # 获取请求上下文中的 'jm' 数据
code_str = data.get('code') # 从数据中获取 'code' 字段,即用户传入的代码
res = capture_print_output(code_str) # 执行代码并捕获输出
res_data = {
'code': code_str, # 返回的结果中包含原始代码
'res': res # 返回的结果中包含代码执行的输出
}
return ok_res(res_data) # 使用 ok_res 函数返回结果
解释:
data = g.jm:获取 Flask 请求上下文中的 g.jm 数据。这通常是前端发送的 JSON 数据,包含了用户提交的代码字符串。code_str = data.get('code'):从 data 中获取 code 字段,即用户传递的 Python 代码字符串。res = capture_print_output(code_str):调用 capture_print_output 函数来执行这段 Python 代码,并捕获其中的 print 输出。res_data:构建一个字典,包含了原始的代码和执行结果。返回的结果中会包含这两部分。return ok_res(res_data):调用 ok_res 函数返回成功响应,res_data 作为响应数据传递。3. capture_print_output 函数:捕获 print 输出
def capture_print_output(code_str):
# 创建一个StringIO对象来捕获输出
captured_output = io.StringIO()
# 将标准输出重定向到StringIO对象
sys.stdout = captured_output
try:
# 执行传入的Python代码
exec(code_str)
except Exception as e:
return [f"Error: {str(e)}"] # 捕获异常并返回错误信息
finally:
# 恢复标准输出
sys.stdout = sys.__stdout__
# 返回捕获的输出并按行分割成列表
return captured_output.getvalue().splitlines()
解释:
-
captured_output = io.StringIO(): - 创建一个
StringIO对象,它模拟一个内存中的文件流,能够捕获并存储print输出。 -
sys.stdout = captured_output: - 将 Python 的标准输出
sys.stdout重定向到captured_output。这样,所有的print语句输出的内容都会被捕获到captured_output中,而不会显示在控制台。 -
exec(code_str): - 使用
exec函数动态执行传入的 Python 代码code_str。这可以执行任意的 Python 代码,适用于动态的场景(如在 Web 应用中执行用户传入的代码)。 -
except Exception as e: - 如果在执行过程中发生错误,会进入
except块,将错误信息以列表形式返回。这可以帮助开发者捕获并显示执行错误。 -
finally: sys.stdout = sys.__stdout__: - 无论执行是否成功,都会执行
finally块,恢复sys.stdout为默认的标准输出,避免影响后续的print输出。 -
captured_output.getvalue().splitlines(): - 使用
captured_output.getvalue()获取捕获到的所有输出,返回一个字符串。 - 然后使用
splitlines()将输出按行分割成一个列表,每一行是一个print输出的内容。
4. 最终结果
假设你向 Flask 路由传递了以下代码:
{
"code": "print('Hello, World!')"
}
在调用 run() 方法时,Flask 会执行 capture_print_output,其中:
exec(code_str) 执行 print('Hello, World!')。print 输出被捕获并存储在 captured_output 中。{
"code": "print('Hello, World!')",
"res": ["Hello, World!"]
}
如果代码中存在错误,例如:
{
"code": "print('Hello World!'"
}
执行时会抛出 SyntaxError,并返回错误信息:
{
"code": "print('Hello World!'",
"res": ["Error: unexpected EOF while parsing"]
}
总结
run 函数处理从客户端传递的 Python 代码,通过 capture_print_output 捕获其输出并返回。capture_print_output 通过 exec 动态执行 Python 代码,并通过重定向 stdout 捕获 print 输出。ok_res 返回给客户端,包含了代码及其执行结果。作者:陈钇谷