我在我的应用程序中嵌入了python解释器。我用它来运行使用PyRun_String()
API的python脚本。如果遇到错误/异常,我可以使用PyErr_Fetch()
获取错误信息。这给了我异常类型,异常值和异常回溯。然后我从traceback中找到原始错误的行号。但是,在语法错误的情况下,我不会得到任何类型的回溯。有人知道如何检索行号而无需追溯..?有没有办法使用异常类型或异常值来检索它..?
Python文档声明:
此类的实例具有filename,lineno,offset和text属性,以便于访问详细信息。异常实例的str()仅返回消息。
如何在嵌入式python中检索SyntaxError的filename和lineno属性??
任何帮助将不胜感激。提前谢谢。
感谢你的建议Brett。 但我已经通过使用PyObject_GetAttr()来尝试它。
请参阅下面用于测试目的的示例代码。
int main(int argc, char** argv)
{
Py_Initialize();
// Get a reference to the main module.
PyObject* main_module =
PyImport_AddModule("__main__");
// Get the main module's dictionary
// and make a copy of it.
PyObject* main_dict =
PyModule_GetDict(main_module);
const char *script_source = "def main():\n\tprint('Hello'\n\nmain()";
PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict);
if(res == NULL)
{
PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
PyErr_Fetch(&ptype,&pvalue,&ptraceback);
PyObject* py_filename = PyUnicode_FromString("filename");
PyObject* file_name = PyObject_GetAttr(ptype,py_filename);
PyObject* py_lineno = PyUnicode_FromString("lineno");
PyObject* line_no = PyObject_GetAttr(ptype,py_lineno);
}
}
我故意在script_source中插入语法错误。
我无法从file_name和line_no对象中检索实际文件名和行号。
我尝试调试file_name和line_no对象,内容如下所示。 “语法错误对象的成员文件名”和“语法错误对象的成员行号”
这些对象不可调用,因此我不能使用PyObject_Call()变体。
有没有办法可以从这些对象中获取实际文件名和行号??
在这个文件名中,我将使用PyRun_String()。
答案 0 :(得分:3)
我通过以下方式解决了这个问题。 我在PyErr_Fetch()之后使用了PyErr_NormalizeException(),现在代码工作正常。
int main(int argc, char** argv)
{
Py_Initialize();
// Get a reference to the main module.
PyObject* main_module =
PyImport_AddModule("__main__");
// Get the main module's dictionary
// and make a copy of it.
PyObject* main_dict =
PyModule_GetDict(main_module);
const char *script_source = "def main():\n\tprint('Hello'\n\nmain()";
PyObject *res = PyRun_String(script_source,Py_file_input,main_dict,main_dict);
if(res == NULL)
{
PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;
PyErr_Fetch(&ptype,&pvalue,&ptraceback);
PyErr_NormalizeException(&ptype,&pvalue,&ptraceback);
char *msg;
char *file;
int line;
int offset;
char *text;
int res = PyArg_ParseTuple(pvalue,"s(siis)",&msg,&file,&line,&offset,&text);
PyObject* file_name = PyObject_GetAttrString(pvalue,"filename");
PyObject* file_name_str = PyObject_Str(file_name);
PyObject* file_name_unicode = PyUnicode_AsEncodedString(file_name_str,"utf-8", "Error");
char *actual_file_name = PyBytes_AsString(file_name_unicode);
PyObject* line_no = PyObject_GetAttrString(pvalue,"lineno");
PyObject* line_no_str = PyObject_Str(line_no);
PyObject* line_no_unicode = PyUnicode_AsEncodedString(line_no_str,"utf-8", "Error");
char *actual_line_no = PyBytes_AsString(line_no_unicode);
printf("done");
}
}
答案 1 :(得分:1)
属性在PySyntaxErrorObject struct上设置,但请注意,如果您遵守Python的稳定ABI,则不会公开该结构。否则,您应该能够使用a PyObject_GetAttr* function来获取属性。