寻求Python稳定ABI中PyRun_String的等效替代方案
替代PyRun_String的stable ABI兼容方案
方案1:使用PyRun_SimpleString(适用于无需自定义命名空间的场景)
如果你的需求只是执行简单Python代码片段,不需要操控globals或locals字典,PyRun_SimpleString属于stable ABI范畴,可直接替代。它会在全局命名空间执行代码,示例:
PyRun_SimpleString("a = 1");
方案2:Py_CompileString + PyEval_EvalCode(支持自定义命名空间)
若需要控制代码执行的globals和locals,这两个函数均属于stable ABI,组合使用可完全实现PyRun_String的功能:
// 编译字符串为代码对象 PyObject* code = Py_CompileString("a = 1", "<string>", start); if (code == nullptr) { // 处理编译错误,比如调用PyErr_Print() return; } // 执行代码对象 PyObject* result = PyEval_EvalCode(code, globals, locals); // 清理对象 Py_XDECREF(code); Py_XDECREF(result);
方案3:调用Python内置exec函数(灵活适配复杂场景)
通过stable ABI提供的API调用Python内置exec函数,行为和Python层面完全一致:
// 获取内置exec函数 PyObject* exec_name = PyUnicode_FromString("exec"); PyObject* builtins = PyEval_GetBuiltins(); PyObject* exec_func = PyDict_GetItem(builtins, exec_name); Py_DECREF(exec_name); if (exec_func == nullptr) { // 错误处理 return; } // 构造调用参数:代码字符串、globals、locals PyObject* args = PyTuple_New(3); PyTuple_SetItem(args, 0, PyUnicode_FromString("a = 1")); PyTuple_SetItem(args, 1, globals); PyTuple_SetItem(args, 2, locals); // 执行exec调用 PyObject* result = PyObject_CallObject(exec_func, args); // 清理资源 Py_XDECREF(args); Py_XDECREF(result);
内容的提问来源于stack exchange,提问作者Nico Schlömer
相关产品推荐
相关产品推荐

