写了一个在线执行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()
    
    解释:
    1. captured_output = io.StringIO()

    2. 创建一个 StringIO 对象,它模拟一个内存中的文件流,能够捕获并存储 print 输出。
    3. sys.stdout = captured_output

    4. 将 Python 的标准输出 sys.stdout 重定向到 captured_output。这样,所有的 print 语句输出的内容都会被捕获到 captured_output 中,而不会显示在控制台。
    5. exec(code_str)

    6. 使用 exec 函数动态执行传入的 Python 代码 code_str。这可以执行任意的 Python 代码,适用于动态的场景(如在 Web 应用中执行用户传入的代码)。
    7. except Exception as e

    8. 如果在执行过程中发生错误,会进入 except 块,将错误信息以列表形式返回。这可以帮助开发者捕获并显示执行错误。
    9. finally: sys.stdout = sys.__stdout__

    10. 无论执行是否成功,都会执行 finally 块,恢复 sys.stdout 为默认的标准输出,避免影响后续的 print 输出。
    11. captured_output.getvalue().splitlines()

    12. 使用 captured_output.getvalue() 获取捕获到的所有输出,返回一个字符串。
    13. 然后使用 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 返回给客户端,包含了代码及其执行结果。
  • 作者:陈钇谷

    物联沃分享整理
    物联沃-IOTWORD物联网 » 写了一个在线执行python的小工具,实现手机编写python代码后运行。

    发表回复