扩展和嵌入Python之获取程序出错信息

Python4Delphi:在Delphi应用中嵌入Python解释器的完整指南 在软件开发中,脚本语言嵌入是扩展原生应用能力的常见技术方案,其核心原理是通过桥接层在宿主进程中加载并控制外部解释器。这种技术能显著提升开发效率,允许开发者复用成熟的第三方生态库,实现“专业工具做专业事”的架构优势。Python作为当前最流行的胶水语言,拥有丰富的数据科学、机器学习与网络爬虫库,而Delphi则是经典的Windows原生应用开发平台。Python4Delphi(P4D)正是连接这两大生态的桥梁,它通过在Delphi进程中嵌入完整的Python解释器,让开发者能在保持VCL/FireMonkey 阅读详情

接着我们上次的内容继续。简单回顾下,上次的这种嵌入方式在Python中称为纯嵌入,我们可以定义自己的模块,在模块中定义自己的函数,通过C API可以让Python解释器识别我们的自定义模块。

在程序调试的过程中,难免会有错误产生,谁也不希望程序出错后一点提示信息也没有,然后就挂了。就像程序员最不喜欢写文档,然后也很痛恨接手的项目没有文档一样~~~如何获取嵌入Python的报错信息,就是本次的主要内容。

回想当时在网上找了好久,终于完成了上一次的程序,还兴奋了好一会儿~~但接下来的问题就是如何获取程序的出错信息。在基于上一次的程序基础上,得出的最终结果是不行!惊不惊喜?刺不刺激?翻阅了网上大部分文章,得出一个非常一致的结论,要用下面的代码片段:PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;

  PyErr_Fetch(&ptype,&pvalue,&ptraceback);

  PyErr_NormalizeException(&ptype,&pvalue,&ptraceback);(可有可无)

 

  if(pvalue)

  {

......

}

但是,并没有说在哪添加......试了N多次无果。最终读了N次stackoverflow(英语还是很重要),从前辈们的只言片语中发现了秘密...帖子的时间好像是2013年吧...

OK,老规矩,直接“上马”。

 

void Widget::on_pbn_runPython_clicked()

{

    qDebug() << "enter python !";

    PyImport_AppendInittab("dahe", &PyInit_math);

 

    Py_Initialize();

    if (!Py_IsInitialized())

    {

        qDebug() << "inital faild!";

    }

 

    PyRun_SimpleString("import dahe");

    QFile f("/root/Python/Article/compilePython/dhTest.py");

 

    if(!f.open(QFile::ReadOnly | QFile::Text))

    {

        qDebug() << "read file faild:" << qPrintable(f.errorString());

    }

    QTextStream stream(&f);

    QString test = stream.readAll();

    QByteArray ba = test.toLatin1();

    const char * script_source = ba.data();

 

    PyObject* main = PyModule_GetDict(PyImport_AddModule("__main__"));

    PyObject *res = PyRun_String(script_source,Py_file_input,main,main);

    if(res == NULL)

    {

        PyObject *ptype = NULL, *pvalue = NULL, *ptraceback = NULL;

        PyErr_Fetch(&ptype,&pvalue,&ptraceback);

        PyErr_NormalizeException(&ptype,&pvalue,&ptraceback);

 

        if(pvalue)

        {

            PyObject *pstr = PyObject_Str(pvalue);

            if(pstr) {

                const char* err_msg = PyUnicode_AsUTF8(pstr);

                if(pstr)

                {

                    printf("%s----\n",err_msg);

                }

            }

        }

 

        char *msg, *file, *text;

        int line, offset;

 

        int res = PyArg_ParseTuple(pvalue,"s(siis)",&msg,&file,&line,&offset,&text);

        Q_UNUSED(res);

 

        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("actual_line_no --%s\n",actual_line_no);

    }

 

    Py_Finalize();

}

 

上述代码是前一次内容的修改,重复部分不再赘述。

使用QFile读取存储文件的内容,该部分简单略过。

在这里看到了PyErr_Fetch(&ptype,&pvalue,&ptraceback)该函数是如何使用的,需要先“编译”python文件,在编译过程中出错才可以调用该函数捕获出错信息。PyObject *res = PyRun_String(script_source,Py_file_input,main,main)注意后面的两个main,如果传为NULL,有时测试出错会报出PyEval_EvalCodeEx: NULL globals这个出错信息,注意下。

PyErr_NormalizeException(&ptype,&pvalue,&ptraceback)该函数用于将异常信息格式化输出,根据需要来使用。不使用的话会捕获到更原始的信息。

PyObject *pstr = PyObject_Str(pvalue) 、const char* err_msg = PyUnicode_AsUTF8(pstr),python C API中的类型大多是PyObject *,这里提供了一种转为c中char*的方法。

Q_UNUSED(res),Qt中提供的一种消除无用参数警告的方式,该宏的函数原型是(void)()。

程序的最后部分是获取出错信息的位置,也就是行号。Pvalue捕获的是出错的内容,有时也会有行号。

至此,程序简单说明结束。下面给出脚本内容以及捕获的具体出错内容。

 

 

 

 

 

如果觉得还阔以,可以关注我的公众号,欢迎大家交流。

 

24、Python扩展、嵌入与调试技巧 本文介绍了Python扩展中的引用计数管理、如何将Python嵌入到C或C++应用程序中,并提供了多个调试Python应用程序的实用技巧。通过详细示例和工具分析,帮助开发者更好地掌握Python扩展、嵌入及调试的核心要点,从而提升代码的稳定性和开发效率。 阅读详情

相关推荐

Cursor设置界面汉化保姆级教程:手把手教你修改JS文件实现中文界面(附避坑指南)

本文提供Cursor编辑器设置界面汉化的详细教程,从定位JS文件到安全修改实现中文界面,包含必备工具清单、文件路径指引和常见问题解决方案。通过手把手教学帮助用户轻松完成汉化,提升使用体验,特别适合不熟悉英文界面的开发者。

weixin_29007809的博客 1414

第五章 异常处理(中)

void PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback) 这是稳定的ABI的一部分。设置来自这三个对象的错误指示器。如果已设置了错误指示器,则将首先清除它。如果这些对象为NULL,则会清除错误指示器。不要传递NULL类型和非NULL值或回溯。异常类型应该是一个类。不要传递无效的异常类型或值。(违反这些规则会在以后造成一些微妙的问题。)此调用带走对每个对象的引用:在调用和调用之前必须拥有对每个对象的引用,之后您不再拥有这些

DTCloud 1316

独立游戏开发者的新武器:实测腾讯混元3D自动绑骨,搭配Mixamo让角色动画制作效率翻倍

本文实测腾讯混元3D自动绑骨功能与Mixamo动画库的协同使用,显著提升独立游戏开发者的角色动画制作效率。通过解决卡通角色绑骨偏差、优化骨骼权重及动画状态机配置,使原本两周的流程缩短至三天,并分享Unity中的性能优化与版权合规要点。

weixin_42662605的博客 497

Python/C API 异常处理

Python/C API 异常处理 Python/C API 中的异常处理与Unix系统中的errno 变量类似,每个线程都有一个全局的异常指示器,该指示器只记录最后一次发生的异常。大多数函数都不会在成功执行时清除该指示器,但会在异常发生时及时设置该指示器。大部分函数函数也都会返回一个标志来指示其执行过程中是否发生异常,如果函数的返回类型为指针,则返回NULL时表示有异常发生;若返回类型为整数,

^_^ 3510

S7-1200 PN与G120变频器控制起停及调速PROFINET实现详解

S7-1200 PLC与G120变频器通过PROFINET通信可实现高效、实时的电机控制。2. 《S7-1200与G120 CU250S-2PN的PROFINET通讯指南》- 控制器:S7-1200 PLC (如1214C DC/DC/DC)- 变频器:G120 CU250S-2PN (带PROFINET接口)- 输出区(PZD1-2):控制字(16位)、速度设定值(16位)- 输入区(PZD1-2):状态字(16位)、实际速度值(16位)- P922=1:选择报文类型为"标准报文1 (PZD2/2)"

电工 1867

innovus:streamOut gds中pg text带有冒号(:)解决办法

streamOut后查看layout,发现部分PG text后面加了冒号,比如VDD: / VSS:。当然,这个问题还有另一种解决办法,就是通过脚本给terminal打text再streamOut。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 1190

Python3 获取异常的信息和traceback(实现类似PyErr_Print功能)

void fetch_error() { PyObject *type = NULL, *value = NULL, *traceback = NULL; PyErr_Fetch(&type, &value, &traceback); if (type) { std::cout << PyExceptionClass_Name(type) << ": "; } if (va

zlyong0018的专栏 7703

YOLOv11模型压缩技术全面对比:剪枝、量化、蒸馏的原理与实战

YOLOv11模型压缩技术综述 模型压缩技术是解决计算资源受限环境下部署深度学习模型的关键。本文系统介绍了YOLOv11模型压缩的三种核心技术:剪枝、量化和蒸馏。剪枝技术通过移除冗余参数实现模型轻量化,包括结构化剪枝(通道/卷积核剪枝)和非结构化剪枝;量化技术通过降低数值精度(如FP32→INT8)减少存储和计算量;蒸馏技术则利用教师模型指导学生模型训练,在保持精度的同时减小模型规模。三种技术可单独或组合使用,在工业质检、智慧安防等边缘计算场景中发挥重要作用,使YOLOv11在保持80%精度的同时减少70%

本博客聚焦 YOLOv11 全流程落地,涵盖架构优化、数据集处理、训练技巧与多场景部署,兼及国产数据库、Java 开发与 AI 模型应用,内容兼顾理论与工程实践,为开发者提供系统干货,助力高效提升技术能力。 579

python获取异常信息,如何获取Python异常文本

I want to embed python in my C++ application. I'm using Boost library - great tool. But i have one problem.If python function throws an exception, i want to catch it and print error in my application ...

weixin_39625429的博客 413

PINN求解PDE

PINN求解Dirichlet泊松方程 泊松方程引入 −Δu=f,x∈Ω=(0,1)2-\Delta u=f,x \in \Omega=(0,1)^2−Δu=f,x∈Ω=(0,1)2 u=g,x∈∂Ωu=g,x \in \partial \Omegau=g,x∈∂Ω import torch import time import numpy as np import matplotlib.pyplot as plt import torch.nn as nn def UU(X, order,prob):

forrestguang的博客 3806

【Unity】RPG2D龙城纷争(十九)流程与UI界面(终章)

本章为RPG2D系列的终章,在之前的章节中我们已经完成了游戏的所有基本功能,那么用流程与UI界面将其串联起来才是我们整个游戏原型完善的标志。

神码编程 917

python 从地址获取数据失败_扩展和嵌入Python之获取程序出错信息 !

接着我们上次的内容继续。简单回顾下,上次的这种嵌入方式在Python中称为纯嵌入,我们可以定义自己的模块,在模块中定义自己的函数,通过C API可以让Python解释器识别我们的自定义模块。在程序调试的过程中,难免会有错误产生,谁也不希望程序出错后一点提示信息也没有,然后就挂了。就像程序员最不喜欢写文档,然后也很痛恨接手的项目没有文档一样~~~如何获取嵌入Python的报错信息,就是本次的主要内容...

weixin_39981400的博客 251

RT-DETR算法优化改进:轻量级上采样CARAFE算子 | 注意力机制大作战

上采样操作CARAFE,具有感受野大、内容感知、轻量级、计算速度快等优点,引入RT-DETR二次创新;1)代替Upsample进行使用;

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 1266

获取input内容并回填_扩展和嵌入Python之获取程序出错信息 !

接着我们上次的内容继续。简单回顾下,上次的这种嵌入方式在Python中称为纯嵌入,我们可以定义自己的模块,在模块中定义自己的函数,通过C API可以让Python解释器识别我们的自定义模块。 在程序调试的过程中,难免会有错误产生,谁也不希望程序出错后一点提示信息也没有,然后就挂了。就像程序员最不喜欢写文档,然后也很痛恨接手的项目没有文档一样~~~如何获取嵌入Python的报错信息,就是本次的主要内...

weixin_36242516的博客 90

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

c++中嵌入python

https://www.cnblogs.com/earvin/p/5423868.html c++中嵌入python入门1 本人是用vc2003+python2.5学习的,其它的也应该差不了多少 0. 坏境设置 把Python的include/libs目录分别加到vc的include/lib directories中去。另外,由于python没有提供debug lib,体地说,就是没有提供p...

steve_cui的博客 2104

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

混合编程—C++程序中python脚本的嵌入方法(理论部分)

本文概述了C++与Python高级编程语言的特点及其优势,并阐述了Python作为脚本语言与C++混合编程的优势与特点,最后针对一些实际项目发布流程进行了理解学习记录。

不要仅为成功而努力,要为做一个有价值的人而努力 2803

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

python字符串无效的原因_Python(60)扩展和嵌入1.使用 C 或 C++ 扩展 Python

1.使用 C 或 C++ 扩展 Python如果你会用 C,添加新的 Python 内置模块会很简单。以下两件不能用 Python 直接做的事,可以通过extension modules来实现:实现新的内置对象类型;调用 C 的库函数和系统调用。为了支持扩展,Python API(应用程序编程接口)定义了一系列函数、宏和变量,可以访问 Python 运行时系统的大部分内容。Pyth...

weixin_34237125的博客 494

python好还是c+-嵌入式系统中,Python与C/C++哪方更为适用?

【51CTO.com快译】长久以来,C/C++一直编译着嵌入式系统编程领域,但二者亦拥有自己的缺陷。相比之下,Python则成为嵌入式系统中的另一大***语言选项。在今天的文章中,我们将共同探讨双方的优劣与Python在嵌入式编程领域的定位。C/C++属于编译语言,而Python则属于解释语言。C语言最初诞生于1969年,C++则出现在1983年,相比之下1989年才开发完成的Python显然更为...

weixin_37988176的博客 545

c malloc 头文件_Python(60)扩展和嵌入1.使用 C 或 C++ 扩展 Python

1.使用 C 或 C++ 扩展 Python如果你会用 C,添加新的 Python 内置模块会很简单。以下两件不能用 Python 直接做的事,可以通过extension modules来实现:实现新的内置对象类型;调用 C 的库函数和系统调用。为了支持扩展,Python API(应用程序编程接口)定义了一系列函数、宏和变量,可以访问 Python 运行时系统的大部分内容。Pyth...

weixin_39608118的博客 293

python定义float类型数组_Python(61)扩展和嵌入2.自定义扩展类型2.1.基础

友情提示:此为高阶主题,初级码农请绕行。2. 自定义扩展类型:教程Python 允许编写 C 扩展模块定义可以从 Python 代码中操纵的新类型,这很像内置的str和list类型。所有扩展类型的代码都遵循一个模式,但是在您开始之前,您需要了解一些细节。这份文件是对这个主题介绍。2.1.基础CPython运行时将所有 Python 对象都视为类型PyObject*的变量,...

weixin_29876887的博客 1922

有汇编功能的python编译器_PyAsm-在python中嵌入汇编

PyAsm是由Python写的动态编译器,使用PyAsm还可以在Python中嵌入汇编语言,用汇编语言来编写Python函数。这听起来很疯狂,但也许你真的需要在python中使用汇编语言。起官方网站为http://members.verizon.net/~olsongt/usersGuide.html其实很久之前就发现了PyAsm,但是初期的尝试并不成功。官方网站并没有给太多的例子,刚开始也没有完...

weixin_32200329的博客 932

嵌入式python c++_嵌入式系统中的Python与C / C ++

嵌入式python c++ 尽管C / C ++编程语言有很多缺点,但它们在嵌入式系统编程中占主导地位。 另一方面,Python具有许多优势,使其成为嵌入式系统的绝佳语言。 让我们看一下每种方法的优缺点,以及为什么应该考虑将Python用于嵌入式编程。 C / C ++是编译语言,而Python是解释语言。 C / C ++已经存在了很长时间。 C最早是在1969年开发的,而C ++则是在1...

cumj63710的博客 861

python扩展c教程_使用C/C++扩展Python

如果你会用C,实现Python嵌入模块很简单。利用扩展模块可做很多Python不方便做的事情,他们可以直接调用C库和系统调用。为了支持扩展,Python API定义了一系列函数、宏和变量,提供了对Python运行时系统的访问支持。Python的CAPI由C源码组成,并包含“Python.h”头文件。编写扩展模块与你的系统相关,下面会详解。目录1一个简单的例子2关于错误和异常3回到例子4模...

weixin_39856803的博客 450

青岛嵌入式与python选哪个_嵌入式系统中,Python与C/C++哪方更为适用?

【51CTO.com快译】长久以来,C/C++一直编译着嵌入式系统编程领域,但二者亦拥有自己的缺陷。相比之下,Python则成为嵌入式系统中的另一大***语言选项。在今天的文章中,我们将共同探讨双方的优劣与Python在嵌入式编程领域的定位。C/C++属于编译语言,而Python则属于解释语言。C语言最初诞生于1969年,C++则出现在1983年,相比之下1989年才开发完成的Python显然更为...

weixin_34503235的博客 197

LangExtract与现有工作流集成:如何将信息提取嵌入到你的应用程序中

LangExtract是一个强大的Python库,专门用于从非结构化文本中提取结构化信息。它利用大型语言模型的能力,将杂乱的文本数据转化为组织良好的结构化格式,同时确保提取结果与源文本精确对应。本文将详细介绍如何将LangExtract无缝集成到你的现有工作流和应用程序中。 ## 为什么需要结构化信息提取? 🤔 在当今数据驱动的世界中,我们每天都会接触到大量的非结构化文本数据:健康记录、法律

gitblog_00061的博客 779
上一篇: 请查收一封绿色的情书
下一篇: 众生皆苦,愿你被世界温柔以待
Pou光明
博客等级 码龄12年 3701粉丝 398原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值