一文就能全部搞定!Python技能提升——异常传播轨迹

当程序出现错误时,系统会自动引发异常,除此之外,Python也允许程序自行引发异常,自行引发异常使用raise语句完成。

使用raise引发异常

如果在程序中需要自行引发异常,则应该使用raise语句,raise语句有如下三种常用的用法:

1. raise: 单独一个raise

该语句引发现在上下文中捕获到的异常(如在except块中),或默认引发RuntimeError异常

2. raise 异常类: raise后带一个异常类

该语句引发指定异常类的默认实例

3. raise 异常对象: 引发指定的异常对象

即使是用户自行引发的异常,也可以通过try…except进行捕获,当然也可以不管它,让该异常向上(先调用者)传播,如果该异常传到Python解释器,则程序就会中止。

如下示例示范了处理用户引发异常的两种方式:

由上面程序可以知道,程序即可在调用mtd(3)时使用try…except来捕获异常,这样改异常将会被except块捕获,不会传播给调用它的函数;也可直接调用mtd(3),这样该函数的异常就会直接传播给它的调用函数,如果该函数也不处理该异常,就会导致程序中止。

运行上面程序,输出结果如下:

上面第一行输出的是第一次调用mtd(3)的结果,该方法引发的异常被except块捕获并处理。

后面的大段输出是第二次调用mtd(3)的结果,由于该异常没有被except块捕获,因此该异常一直向上传播,直到传给Python解释器导致程序中止。

注意:第二次调用mtd(3)引发的以“File”开头的三行输出,其实现实的就是异常的传播轨迹信息,即如果程序不对异常进行处理,Python默认会在控制台输出异常的传播轨迹信息。

推荐 :020 持续更新,精品小圈子每日都有新内容,干货浓度极高。
结实人脉、讨论技术 你想要的这里都有!
抢先入群,跑赢同龄人!(入群无需任何费用)
点击此处,与Python开发大牛一起交流学习。
群号:745895701
申请即送:
Python软件安装包,Python实战教程
资料免费领取,包括 Python基础学习、进阶学习、爬虫、人工智能、自动化运维、自动化测试等

自定义异常类

用户自定义异常都应该继承Exception基类或Exception的子类,在自定义异常类时基本不需要写更多的代码,只需要指定自定义异常类的父类即可。

如下所示:

class AuctionException(Exception):

pass

上面程序创建了AuctionException异常类,该异常类不需要类体定义,因此使用pass语句作为占位符即可。

except和raise同时使用

在实际应用中对异常可能需要更复杂的处理方式——当一个异常出现时,单靠某个方法无法完成处理该异常,必须由几个方法协作才可完全处理该异常。即在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要在该方法的调用者中才能完成,所以应该再次引发异常,让该方法的调用者也能捕获异常。

为了实现这种通过多个方法协作处理同一个异常的情形,可在except块中结合raise语句完成,如下:

上面程序中AuctionTest类中except块捕获到异常后,系统打印了该异常的字符串信息,接着引发一个AuctionException异常,通知该方法的调用者再次处理该AuctionException异常。所以程序中的main()函数,也就是bid()方法的调用者还可再次捕获AuctionException异常,并将该异常的详细描述信息打印出来。

Python的异常传播轨迹

异常对象提供了一个with_traceback用于处理异常的传播轨迹,查看异常的传播轨迹可追踪异常触发的源头,也可看到异常一路触发的轨迹。

如下示例:

上面程序中main()函数调用firstMethod(),firstMethod()调用secondMethod(),secondMethod()调用thirdMethod(),thirdMethod()直接引发一个SelfException异常。

运行上面程序,将会看到如下结果:

可以看出,异常从thirdMethod()函数开始触发,传到secondMethod()函数,再传到firstMethdo()函数,最后传到main()函数,在main()函数中止,这个过程就是Python的异常传播轨迹。

在实际应用程序的开发中,大多数可重用操作都会被分解成一系列函数或方法调用,这是因为为了具有更好的可重用性,会将每个可重用的代码单元定义成函数或方法,将复杂任务逐渐分解为更容易管理的小型子任务。由于一个大的业务功能需要由多个函数或方法共同实现,在最终编程模型中,很多对象将通过一系列函数或方法调用来实现通信,执行任务。

所以,当应用程序运行时,经常会发生一系列函数或方法调用,从而形成“函数调用栈”,异常的传播则相反:只要异常没有被完全捕获(包括异常没有被捕获,或异常被处理后重新引发了新异常),异常就从发生异常的函数或方法逐渐向外传播,首先传给该函数或方法的调用者,该函数或方法的调用者再传给其调用者…直至最后传到Python解释器,此时Python解释器会中止该程序,并打印异常的传播轨迹信息。

Python专门提供了traceback模块来处理异常传播轨迹,使用traceback可方便地处理Python的异常传播轨迹。

导入traceback模块之后,traceback提供了如下两个常用方法:

1. traceback.print_exc(): 将异常传播轨迹信息输出到控制台或指定文件中

2. format_exc(): 将异常传播轨迹信息转换成字符串

到这里可能你有疑问:从上面方法看不出它们到底处理哪个异常的传播轨迹信息?

OK,实际上常用的print_exc()是print_exc([limit[,file]])省略了limit、file两个参数的形式。

其中,limit用于限制显示异常传播的层数,比如函数A调用函数B,函数B发生了异常,如果指定limit=1,则只显示函数A里面发生的异常,如果不设置limit参数,则默认全部显示。

file指定将异常传播轨迹信息输出到指定文件中,如果不指定该参数,则默认输出到控制台。

示例如下:

上面程序中第一行先导入traceback模块,接下来程序使用except捕获程序的异常,并使用traceback的print_exc()方法输出异常传播信息,分别将它输出到控制台和指定文件中。

运行上面程序,同样可看到在控制台输出异常传播信息,且在程序目录下生成了一个log.txt文件,该文件中同样记录了异常传播信息。

最后说一下异常处理的规则:

一般来说,成功的异常处理应该事先如下4个目标:

1. 使程序代码混乱最小化

2. 捕获并保留诊断信息

3. 通知合适的人员

4. 采用合适的方式结束异常活动

### 高斯过程回归概述 高斯过程回归(Gaussian Process Regression, GPR)是一种非参数化的贝叶斯方法,广泛应用于时间序列预测、函数逼近和不确定性估计[^2]。作为一种基于高斯过程理论的方法,GPR特别适合处理具有不确定性的数据,并能提供概率分布形式的结果。 #### 基本概念 高斯过程可以被理解为随机变量的集合,其中任意有限数量的这些随机变量都服从联合正态分布[^1]。具体来说,如果 \( \{f(x), x\in X\} \) 是一个高斯过程,则对于任何有限子集 \( (x_1,...,x_n)\subset X \),向量 \( f=(f(x_1),...,f(x_n))^\top \) 应该遵循多元正态分布: \[ p(f|x)=N(\mu,\Sigma) \] 这里 \( N() \) 表示多维正态分布;\( μ \) 和 \( Σ \) 分别代表均值向量与协方差矩阵。而协方差矩阵中的元素由核函数计算得出,即 \( K_{ij}=k(x_i,x_j) \)[^3]。 #### 实现流程 为了实现高斯过程回归模型,通常会经历以下几个阶段: - **定义先验分布**:设定合适的超参来构建初始假设空间; - **选择合适核函数**:根据问题特性挑选恰当类型的核函数作为相似度衡量标准; - **训练样本拟合**:利用已知输入输出对更新后验分布; - **测试新实例推断**:通过最大化似然或者最小化误差准则得到最优解并给出置信区间。 下面是一段简单的Python代码演示如何使用`scikit-learn`库来进行基本的高斯过程回归操作: ```python from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process.kernels import RBF, ConstantKernel as C # 定义RBF核函数及其对应的长度尺度参数l=0.1 kernel = C(1.0, (1e-3, 1e3)) * RBF(length_scale=0.1) gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10) X_train = [[-1], [0], [1]] # 训练特征 y_train = [-2, 0, 2] # 对应的目标值 gp.fit(X_train, y_train) # 拟合模型 X_test = [[-0.8], [0.8]] # 测试特征 mean_prediction, std_prediction = gp.predict(X_test, return_std=True) print(mean_prediction) # 输出预测均值 print(std_prediction) # 输出预测标准偏差 ``` 此段代码展示了怎样创建一个带有径向基函数(RBF)核的高斯过程对象,并对其进行训练以适应给定的数据点。之后再用这个经过训练后的模型去预测新的未知位置处可能存在的目标数值及其相应的不确定性水平。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值