You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C/C++实现支持持续会话的交互式Python控制台?

交互式Python Shell的C语言实现示例

要实现持续会话的交互式Python调用,你可以使用PyRun_InteractiveLoop函数(复用Python原生交互逻辑),或者手动循环处理输入、执行代码并捕获输出。以下是两种实用实现方式:

方式一:基于PyRun_InteractiveLoop快速实现

这个方法直接复用Python内置的交互循环,代码简洁,体验和原生Python shell一致:

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stdio.h>

int main(int argc, char *argv[]) {
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);
    Py_Initialize();

    // 从标准输入读取指令,持续执行直到退出
    PyRun_InteractiveLoop(stdin, "<stdin>");

    if (Py_FinalizeEx() < 0) {
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

说明

  • PyRun_InteractiveLoop会自动处理多行输入、提示符(>>>/...)、异常提示等逻辑,用户输入exit()或按下Ctrl+D即可退出会话。

方式二:手动控制输入输出(自定义交互逻辑)

如果需要自定义输入读取、输出存储或会话规则,可以手动循环执行代码,结合输出重定向实现:

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <stdio.h>
#include <string.h>

// 重定向Python输出的回调函数
static int redirect_output(PyObject *self, PyObject *args) {
    const char *output;
    if (!PyArg_ParseTuple(args, "s", &output)) {
        return 0;
    }
    // 此处可将输出写入自定义缓冲区,示例直接打印到终端
    printf("%s", output);
    return 0;
}

static PyMethodDef RedirectMethods[] = {
    {"write", redirect_output, METH_VARARGS, "Redirect Python output"},
    {NULL, NULL, 0, NULL}
};

static struct PyModuleDef redirectmodule = {
    PyModuleDef_HEAD_INIT,
    "redirect",
    NULL,
    -1,
    RedirectMethods
};

PyMODINIT_FUNC PyInit_redirect(void) {
    return PyModule_Create(&redirectmodule);
}

int main(int argc, char *argv[]) {
    wchar_t *program = Py_DecodeLocale(argv[0], NULL);
    if (program == NULL) {
        fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
        exit(1);
    }
    Py_SetProgramName(program);
    Py_Initialize();

    // 替换sys.stdout,捕获Python输出
    PyObject *sys_module = PyImport_ImportModule("sys");
    PyObject *redirect_module = PyImport_ImportModule("redirect");
    PyObject *redirect_write = PyObject_GetAttrString(redirect_module, "write");
    PyObject_SetAttrString(sys_module, "stdout", redirect_write);
    // 释放临时引用
    Py_XDECREF(sys_module);
    Py_XDECREF(redirect_module);
    Py_XDECREF(redirect_write);

    char input_buf[1024];
    printf(">>> ");
    while (fgets(input_buf, sizeof(input_buf), stdin) != NULL) {
        // 去除换行符
        input_buf[strcspn(input_buf, "\n")] = '\0';
        if (strcmp(input_buf, "exit") == 0) {
            break;
        }

        // 执行输入的Python代码
        PyObject *main_module = PyImport_AddModule("__main__");
        PyObject *global_dict = PyModule_GetDict(main_module);
        PyObject *result = PyRun_String(input_buf, Py_single_input, global_dict, global_dict);

        if (result == NULL) {
            // 打印异常信息
            PyErr_Print();
        } else {
            // 输出执行结果
            PyObject *repr = PyObject_Repr(result);
            char *result_str = PyUnicode_AsUTF8(repr);
            printf("%s\n", result_str);
            // 释放引用
            Py_XDECREF(repr);
            Py_XDECREF(result);
        }

        printf(">>> ");
    }

    if (Py_FinalizeEx() < 0) {
        exit(120);
    }
    PyMem_RawFree(program);
    return 0;
}

说明

  1. 输出重定向:通过自定义Python模块替换sys.stdout.write,可以将Python的输出捕获到自定义缓冲区或其他存储位置。
  2. 会话控制:手动读取用户输入,支持自定义退出指令(示例中为exit),灵活控制会话生命周期。
  3. 结果处理:捕获代码执行结果,将其转为字符串输出;若执行出错,自动打印异常信息。

编译注意事项

Linux下编译需链接Python库:

gcc -o python_interactive python_interactive.c $(python3-config --cflags --ldflags)

Windows下需配置Python的包含目录和库目录,链接对应版本的pythonXY.lib(XY为Python版本号,如python311.lib)。

内容的提问来源于stack exchange,提问作者user19095524

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:30:27