python自定义异常

2023-05-16

python自定义异常

raise

​ python的异常有两种,一种是python自带的异常,当我们写的代码在语法或其他功能的调用上有误时,如果没有异常捕捉的话代码运行会直接报错的,都算这一类。另一种就是当我们觉得,仅仅只是针对语法方面的报错已经不能满足我们的要求了,我们希望在某些逻辑的环节上,虽然语法没有错,但也要主动报错,以避免按照错误的逻辑继续执行,后面这一种就属于自定义异常,为的就是在我们需要的时候抛出一个异常。

​ 凡是自定义异常就绕不开一个关键词——raise,其作用就是主动抛出异常。raise 语句有如下三种常用的用法:

  1. raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。
  2. raise 异常类名称:raise 后带一个异常类名称,表示引发执行类型的异常。
  3. raise 异常类名称(描述信息):在引发指定类型的异常的同时,附带异常的描述信息。
# 用法一:
>>> raise
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    raise
RuntimeError: No active exception to reraise
    

# 用法二:
>>> raise ZeroDivisionError
Traceback (most recent call last):
  File "<pyshell#0>", line 1, in <module>
    raise ZeroDivisionError
ZeroDivisionError


# 用法三:
>>> raise ZeroDivisionError("除数不能为零")
Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    raise ZeroDivisionError("除数不能为零")
ZeroDivisionError: 除数不能为零

​ 实际上用得比较多的是第三种,这样的用法意味着我们可以在原有的异常类型中,将报错信息修改成我们想要的内容;也意味着我们可以自己写一个报错类型,然后根据不同情景抛出不同的报错信息。

下面简单写一个阶乘的函数来展示raise不同的应用方式:

基于基类修改报错信息,直接放在一个逻辑中

def factorial(num):
    try:
        if num < 0 or type(num) != int:
            raise Exception("该数不能阶乘")
    	else:
            return num * factorial(num-1)
    except Exception as e:
        print(e)

就正常的逻辑来讲,当参数小于零或者不是整型时,代码也是可以继续往下执行的,但得到的并不是我们想要的结果,所以要结束掉 然后再给一个反馈。raise语句其中的作用就是引发一个报错,再让外部的异常捕捉机制来处理。

定义一个新的异常类

class NewException(Exception):
    def __init__(self,errorinfo):
        super().__init__(self)
        self.errorinfo = errorinfo
    def __str__(self):
        return self.errorinfo
    
def factorial(num):
    try:
        if num < 0 or type(num) != int:
            raise NewException("我说你错了,你就是错了")
    	else:
            return num * factorial(num-1)
    except Exception as e:
        print(e)

这种方式是常用的,而且上面的这个类NewException是一个通用的模板,你可以把你想要抛出的异常全部归到这里来,然后不同场景添加不同的报错信息就是了。在这里顺便提一下异常的继承关系,Exception是异常处理过程中所有异常的基类。所有的异常捕捉可以直接指定捕捉某一个具体的异常(如:except NameError:),也可以直接笼统地捕捉所有异常(except Exception:),我们定义新的类也是继承自Exception,继承更上级或更下级类也可以,没多大必要。

(图片来自网络:https://www.jianshu.com/p/24e6fb03d6d6)

img

写一个装饰器

这种形式只是我最近刚整理完装饰器的知识,在这里融汇贯通一下,写着玩的。不常用,也不推荐。

def decator(fun):
    def inner(num):
        try:
            if num < 0 or type(num) != int:
            	raise Exception("我说你错了,你就是错了")
            else:
               return fun(num)
        except Exception as e:
            print(e)
    return inner

@decator
def factorial(num):
    return 1 if num == 0 or num == 1 else num * factrial(num-1)

assert断言

​ 断言语句也是一种主动抛出异常的方式,是我个人用得比较多的方式。其原理为,如果断言给出的命题为真则继续往下执行,否则直接抛出异常AssertionError。另外,断言语句也可以自定义报错信息,其写法为:assert 判断语句 [,报错信息]

def factorial(num):
    assert num >=0 and type(num) == int,"该数不能阶乘"
    return 1 if num == 0 or num == 1 else num * factorial(num-1)

ssert num >=0 and type(num) == int,“该数不能阶乘”
return 1 if num == 0 or num == 1 else num * factorial(num-1)


此外,assert断言语句也可以跟raise语句结合使用,大家有兴趣的话也可以找其他帖子了解一下,本文不再赘述
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python自定义异常 的相关文章

  • 通过 add_subplot 添加子图后如何共享轴?

    我有一个像这样的数据框 df pd DataFrame A 0 3 0 2 0 5 0 2 B 0 1 0 0 0 3 0 1 C 0 2 0 5 0 0 0 7 D 0 6 0 3 0 4 0 6 index list abcd A B
  • sklearn 估计器管道的参数无效

    我正在实现 O Reilly 书中的一个示例 Python 机器学习简介 使用 Python 2 7 和 sklearn 0 16 我正在使用的代码 pipe make pipeline TfidfVectorizer LogisticRe
  • 将 JSON 发布到 Python CGI

    我已经安装了 Apache2 并且 Python 可以工作 但我有一个问题 我有两页 一个是 Python 页面 另一个是带有 JQuery 的 Html 页面 有人可以告诉我如何让我的 ajax 帖子正常工作吗
  • 如何在 Debian 上的 virtualenv 中安装 numpy?

    注 参见这另一篇文章 https stackoverflow com questions 6442754 how to install h5py numpylibhdf5 as non root on a debian linux syst
  • 在Python中,如何将矩阵逆时针旋转90度?

    gt gt gt def rotate matrix k List List int For example if I have m 1 2 3 2 3 3 5 4 3 rotate matrix m should give me 3 3
  • Python 转换矩阵

    我有一个如下所示的列表 2 1 3 1 2 3 1 2 2 2 我想要的是一个转换矩阵 它向我显示如下序列 1 后跟 1 的频率是多少 1 后面跟着 2 的频率是多少 1 后跟 3 的频率是多少 2 后跟 1 的频率是多少 2 后跟 2 的
  • 为什么在访问 Python 对象属性时使用 getattr() 而不是 __dict__ ?

    在具有一定程度的 Python 对象自省的源代码示例和 SO 答案中 常见的模式是 getattr some object attribute name string 是否有理由优先选择这种模式 some object dict attri
  • 来自 pandas 数据帧的烛台图,用日期替换索引

    此代码给出了带有移动平均线的烛台图 但 x 轴位于索引中 我需要 x 轴位于日期中 需要做什么改变 import numpy as np import pandas as pd import matplotlib pyplot as plt
  • 将 Python Pandas DataFrame 写入 Word 文档

    我正在努力创建一个使用 Pandas DataFrames 的 Python 生成的报告 目前我正在使用DataFrame to string 方法 但是 这会作为字符串写入文件 有没有办法让我实现这一目标 同时将其保留为表格 以便我可以使
  • django 模板 - 如何动态访问变量?

    假设我有一个具有以下上下文的 django 模板 data1 this is data1 data2 this is data2 data name data2 现在我知道了data name 假设它是 data2 是否可以用它来访问变量d
  • 带有 mkdocs 的本地 mathjax

    我想在无法访问互联网的计算机上使用 MathJax 和 Mkdocs 因此我不能只调用 Mathjax CDN Config mkdocs yml site name My Docs extra javascript javascripts
  • 使用pathlib获取主目录

    翻看新的pathlib在 Python 3 4 中 我注意到没有任何简单的方法来获取用户的主目录 我能想到的获取用户主目录的唯一方法是使用旧的os path像这样的库 import pathlib from os import path p
  • ValueError:数据必须为正(boxcox scipy)

    我正在尝试将我的数据集转换为正态分布 0 8 298511e 03 1 3 055319e 01 2 6 938647e 02 3 2 904091e 02 4 7 422441e 02 5 6 074046e 02 6 9 265747e
  • 数据框中 .map(str) 和 .astype(str) 有什么区别

    我有一个数据框 其列名为 col1 和 col2 的整数类型条目 我想将 col1 和 col2 的条目以及其间的 点 连接起来 我搜索并发现添加两个列条目 df col df col1 map str df col2 map str 并添
  • 将 window.location 传递给 Flask url_for

    我正在使用 python 在我的页面上 当匿名用户转到登录页面时 我想将一个变量传递到后端 以便它指示用户来自哪里 发送 URL 因此 当用户单击此锚链接时 a href Sign in a 我想发送用户当前所在页面的当前 URL
  • 通过 Python 循环浏览网络上的目录并显示其内容(文件和其他目录)

    同样的道理在Python中处理从源目录到目标目录的一组文件 https stackoverflow com questions 2593399 process a set of files from a source directory t
  • 为什么 Collections.counter 这么慢?

    我正在尝试解决罗莎琳德的基本问题 即计算给定序列中的核苷酸 并在列表中返回结果 对于那些不熟悉生物信息学的人来说 它只是计算字符串中 4 个不同字符 A C G T 出现的次数 我期望collections Counter是最快的方法 首先
  • 从 wxPython 事件处理程序中调用函数

    我正在努力寻找一种在 wxPython 事件处理函数中使用函数的方法 假设我有一个按钮 单击该按钮时 它会使用事件处理程序运行一个名为 OnRun 的函数 但是 用户忘记单击 OnRun 按钮之前的 RadionButton 我想弹出一个
  • Django 将 JSON 数据传递给静态 getJSON/Javascript

    我正在尝试从 models py 中获取数据并将其序列化为views py 中的 JSON 对象 模型 py class Platform models Model platformtype models CharField max len
  • 如何使用 enumerate 来倒数?

    letters a b c 假设这是我的清单 在哪里for i letter in enumerate letters 将会 0 a 1 b 2 c 我怎样才能让它向后枚举 如 2 a 1 b 0 c 这是一个很好的解决方案并且工作完美 i

随机推荐