百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

一文速速搞懂Python的异常

off999 2024-11-19 08:33 66 浏览 0 评论

人生之事,不如意者十之有九。

在编程中亦是如此。异常(Exception),遍布于程序各个角落,开发工作的大部分coding,都是为了应对和解决它。

概念

异常,简而言之,是程序在执行期间发生的非预期的、非正常的事件或情况。

举个实际生活的例子:

你周末出门买大龙虾,但当你决定要买哪一只时,你发现没带钱包,那么买大龙虾就是程序要执行的逻辑,而没带钱包就是异常情况。

但异常是一种有一定解决应对方法的错误,就像没带钱包也有可能买得了大龙虾,比如你可以向老板赊账或者暂时借熟人的钱来买。

所以,异常并不一定会完全阻止要完成的事情,有时可能是在提示存在的问题和引导出新的解决方法,应该辩证地去面对它。

产生原因

编程中这些异常的产生可能源自于各种各样的源头,可能是用户提供了错误的输入数据(外因),也可能是系统本身存在逻辑错误(内因)。当这样的异常出现时,如果不加以妥善处理,程序的执行流程将会被强行打断,进而可能引发程序崩溃、数据丢失等严重后果。

家族类型


Python内置了丰富多样的异常类型,每种类型都对应着特定的错误场景。以下是一些常见的异常类型:

  • SyntaxError(语法错误):当代码存在不符合 Python 语法规则的地方时就会引发。例如,遗漏了必要的括号、引号等。
  • NameError(名称错误):当尝试使用一个未定义的变量或函数时产生。
  • TypeError(类型错误):操作中数据类型不匹配导致,比如对一个字符串使用数学运算,1 + "1"
  • ValueError(值错误):提供的值不符合要求,如将一个非数字字符串转换为整数, int("a")
  • IndexError(索引错误):在访问列表等数据结构时,使用了超出范围的索引,比如[][10]
  • KeyError(键错误):在字典中查找不存在的键,比如{}["name"]这样访问就会引发。
  • AttributeError(属性错误):尝试访问对象上不存在的属性就会引发,比如A类没有name属性,而A.name就会引发此异常。
  • ZeroDivisionError(零除错误):尝试除以零就会引发,如1/0
  • IOError(IO错误):输入输出相关的文件流错误, 比如文件流打开异常、网络流访问异常等。
  • FileNotFoundError(文件不存在错误):指定的文件不存在就会引发,比如尝试读写不存在的文件,是IOError的一个细分子类。
  • ImportError(导入模块错误):Python会按照一定的路径搜索模块文件。如果import的模块文件没有在搜索路径中找到,就会引发ImportError错误,比如from math import zero
  • RuntimeError(运行时错误)RuntimeError是一种运行时异常,表示在程序运行过程中发生了一些无法预期的情况而导致的一般性错误。比如资源不足等
  • NotImplementedError(未实现方法异常):当一个方法或操作尚未实现就会引发,比如图形父类要求计算面积方法必须实现(父类方法写着raise NotImplementedError("子类必须实现这个方法")),那么继承了图形父类的三角形子类如果不实现计算面积方法就会引发。
  • IndentationError(缩进错误):代码格式缩进不正确的地方会引发,是SyntaxError的细分子类。
  • KeyboardInterrupt(键盘中断):当键盘按下Ctrl+C时会引发捕获

需要注意的是,BaseException所有异常的基类(注意,不是Exception)。它包括了系统退出相关的异常(如 SystemExit)以及异常中断相关的异常(如 KeyboardInterrupt)等。它位于异常层次结构的最顶端。

Exception继承自BaseException,是大多数用户自定义异常和Python内置异常的直接或间接基类,其他常见的异常如 IOErrorValueErrorTypeError 等都属于 Exception 及其子类。

处理方法

内置异常处理

为了有效地应对这些异常情况,Python 提供了一套强大且灵活的异常处理机制,而其中的核心就是 try-except 语句结构,以及另外两种特殊情况:try-except-elsetry-except-finally。 以下是一个面对ZeroDivisionError(零除错误) 异常的处理示例:

# try-except 示例
try:
    a = 10 / 0  # 会引发异常
except ZeroDivisionError:  # 尝试除以零就会引发——零除错误
    print("捕获到除以零错误")

# try-except-else 示例
try:
    b = 10 / 2
except ZeroDivisionError:
    print("捕获到除以零错误")
else:
    print("在 try 块中没有发生异常时执行这里:", b)

# try-except-finally 示例
try:
    c = 5 / 1
except ZeroDivisionError:
    print("捕获到除以零错误")
finally:
    print("无论是否发生异常都会执行这里")
  • try-except:主要用于捕获和处理特定的异常,当异常发生时执行相应的 except 代码块。
  • try-except-else:在 try 中没有异常发生时,会执行 else 中的代码,它将正常执行的情况和异常处理的情况进行了更明确的区分。
  • try-except-finally:无论是否发生异常,finally 中的代码一定会执行,通常用于进行一些无论如何都要完成的清理或收尾工作。比如关闭文件、释放资源等。

这些内置异常还支持自定义异常消息和主动raise

number = "a"
try:
    if not number.isnumeric():
        raise ValueError("该字符串不能转成数值")
except ValueError as e:
    print(e)

# Outputs
# 该字符串不能转成数值

自定义异常

在现实开发中,python的内置异常类型不足以满足业务上的细分情况,有些是属于规则异常,如输入的邮箱不满足规则要求,这时候就需要引入自定义异常了。

自定义异常实现通常有以下流程:

  • 首先,定义一个继承自Exception的自定义异常类,在类中可以添加一些与该异常相关的属性和构造方法来定制异常信息。
  • 然后,编写一个用于执行具体校验操作的函数,当校验不通过时,主动通过raise抛出自定义异常
  • 在使用的地方,将可能引发异常的代码放在try块中,然后针对自定义异常进行捕获和处理

下面举个web开发中常见的检查邮箱格式例子:

import re

class InvalidEmailException(Exception):
    """自定义异常类"""
    def __init__(self, email):
        self.email = email
        super().__init__(f"无效的邮箱: {email}")

def validate_email(email):
    # 实用正则表达式校验邮箱格式
    pattern = r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+#39;
    if not re.match(pattern, email):
        raise InvalidEmailException(email)

try:
    # 校验邮箱格式
    validate_email("invalid_email")
except InvalidEmailException as e:
    # 捕获到邮箱格式的异常并处理(这里的处理仅仅是打印相关信息)
    print(e)
    
# Outputs
# 无效的邮箱: invalid_email

无法处理的异常

对于一些无法预料的异常,通常需要一个大的try-catch进行捕获,并打印记录到日志系统和告警系统,然后再进一步收集、分析、处理。

应用场景

文件操作

当我们尝试打开一个不存在的文件进行读取或写入时,就可能引发 FileNotFoundError 异常。通过异常处理,我们可以优雅地处理这种情况,比如提示用户文件不存在并引导他们采取正确的行动。

try:
    with open('file.txt', 'r') as f:
        content = f.read()
except FileNotFoundError:
    print("文件不存在!")

网络通信

在与网络服务进行交互的过程中,网络连接问题、服务器错误等都可能导致异常的产生。及时捕获和处理(如重试)这些异常能够让我们的程序更加稳定和可靠。

import requests

try:
    response = requests.get('http://example.com')
except requests.exceptions.RequestException as e:
    print(f"网络请求出错: {e}")

用户输入验证

我们可以利用异常处理来确保用户输入的合法性。当用户输入不符合要求的数据时,引发异常并提示用户重新输入,直到输入正确为止。

while True:
    try:
        age = int(input("请输入你的年龄: "))
        break
    except ValueError:
        print("请输入有效的整数!")

数据库操作

在与数据库进行交互时,可能会遇到连接问题、查询错误等异常情况。通过合理的异常处理,可以保障程序在面对这些问题时依然能够正常运行。

资源管理

当获取或释放系统资源时,如内存、锁等,如果操作出现问题,异常处理可以帮助我们确保资源的正确管理和释放,避免资源泄漏等问题。

外部依赖

当程序依赖于其他外部组件或服务时,如第三方库、外部系统接口等,这些外部因素可能会出现故障或异常。通过异常处理,可以在一定程度上隔离这些外部问题,使我们的程序更具弹性。

业务异常

当程序执行时需要满足某些条件规则,比如需要用户登录后才能进行的操作,如果用户不登录,可能有些功能无权操作。这时我们可以把这种情况视为一种业务异常抛出给用户,并提示引导用户去登录。

在web开发中,有时会通过middleware(中间件/拦截器)或者装饰器的方式对应一些业务异常进行统一捕获,当这些业务异常被抛出时,就会寻找对应方法来处理或引导解决,下面通过一个多种异常统一捕获和处理例子说明下:

class WebError(Exception):
    def handle(self):
        # 最后的底牌处理
        print("服务器升级中")

class NotLoginError(WebError):
    def handle(self):
        # 处理未登录的逻辑,比如跳转登录链接
        print("跳转登录页面")

class InputError(WebError):
    def handle(self):
        # 提示输入有问题的逻辑处理
        print("输入有问题,重新输入")

def web_middleware(func):
    def inner(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except WebError as e:
            # 捕获到异常,并使用多态进行对应处理
            if isinstance(e, WebError):
                return e.handle()
        except Exception:  # 无法预测的异常 
            WebError().handle()
    return inner

# --------------------------- web 接口逻辑 ----------------------------------

@web_middleware
def get_user_info(s):
    """获取用户信息"""
    if s == 1:
        # 假设拿不到用户信息
        raise NotLoginError()
    elif s == 2:
        # 假设用户输入ID不正确
        raise InputError()
    elif s == 3:
        # 假设计算逻辑出错
        s / 0
    else:
        print("获取用户信息成功")

for i in range(1, 5):
    get_user_info(i)
    
# Output
# 跳转登录页面
# 输入有问题,重新输入
# 服务器升级中
# 获取用户信息成功

总结

程序中的异常,恰似人生旅途中的坎坷波折,它们在某些时候反而能促使我们的系统不断磨砺成长,迈向更加健壮与稳定的境界。故而,请以正确的态度和方式“珍视”并“善待”异常。

各位彦祖亦菲,你是怎么看待异常的呢?

相关推荐

安全教育登录入口平台(安全教育登录入口平台官网)

122交通安全教育怎么登录:122交通网的注册方法是首先登录网址http://www.122.cn/,接着打开网页后,点击右上角的“个人登录”;其次进入邮箱注册,然后进入到注册页面,输入相关信息即可完...

大鱼吃小鱼经典版(大鱼吃小鱼经典版(经典版)官方版)

大鱼吃小鱼小鱼吃虾是于谦跟郭麒麟的《我的棒儿呢?》郭德纲说于思洋郭麒麟作诗的相声,最后郭麒麟做了一首,师傅躺在师母身上大鱼吃小鱼小鱼吃虾虾吃水水落石出师傅压师娘师娘压床床压地地动山摇。...

谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
  • 谷歌地球下载高清卫星地图(谷歌地球地图下载器)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)
哪个软件可以免费pdf转ppt(免费的pdf转ppt软件哪个好)

要想将ppt免费转换为pdf的话,我们建议大家可以下一个那个wps,如果你是会员的话,可以注册为会员,这样的话,在wps里面的话,就可以免费将ppt呢转换为pdfpdf之后呢,我们就可以直接使用,不需要去直接不需要去另外保存,为什么格式转...

2026-02-04 09:03 off999

电信宽带测速官网入口(电信宽带测速官网入口app)

这个网站看看http://www.swok.cn/pcindex.jsp1.登录中国电信网上营业厅,宽带光纤,贴心服务,宽带测速2.下载第三方软件,如360等。进行在线测速进行宽带测速时,尽...

植物大战僵尸95版手机下载(植物大战僵尸95 版下载)

1可以在应用商店或者游戏平台上下载植物大战僵尸95版手机游戏。2下载教程:打开应用商店或者游戏平台,搜索“植物大战僵尸95版”,找到游戏后点击下载按钮,等待下载完成即可安装并开始游戏。3注意:确...

免费下载ppt成品的网站(ppt成品免费下载的网站有哪些)

1、Chuangkit(chuangkit.com)直达地址:chuangkit.com2、Woodo幻灯片(woodo.cn)直达链接:woodo.cn3、OfficePlus(officeplu...

2025世界杯赛程表(2025世界杯在哪个国家)

2022年卡塔尔世界杯赛程公布,全部比赛在卡塔尔境内8座球场举行,2022年,决赛阶段球队全部确定。揭幕战于当地时间11月20日19时进行,由东道主卡塔尔对阵厄瓜多尔,决赛于当地时间12月18日...

下载搜狐视频电视剧(搜狐电视剧下载安装)

搜狐视频APP下载好的视频想要导出到手机相册里方法如下1、打开手机搜狐视频软件,进入搜狐视频后我们点击右上角的“查找”,找到自已喜欢的视频。2、在“浏览器页面搜索”窗口中,输入要下载的视频的名称,然后...

pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
  • pubg免费下载入口(pubg下载入口官方正版)
永久免费听歌网站(丫丫音乐网)

可以到《我爱音乐网》《好听音乐网》《一听音乐网》《YYMP3音乐网》还可以到《九天音乐网》永久免费听歌软件有酷狗音乐和天猫精灵,以前要跳舞经常要下载舞曲,我从QQ上找不到舞曲下载就从酷狗音乐上找,大多...

音乐格式转换mp3软件(音乐格式转换器免费版)

有两种方法:方法一在手机上操作:1、进入手机中的文件管理。2、在其中选择“音乐”,将显示出手机中的全部音乐。3、点击“全选”,选中所有音乐文件。4、点击屏幕右下方的省略号图标,在弹出菜单中选择“...

电子书txt下载(免费的最全的小说阅读器)

1.Z-library里面收录了近千万本电子书籍,需求量大。2.苦瓜书盘没有广告,不需要账号注册,使用起来非常简单,直接搜索预览下载即可。3.鸠摩搜书整体风格简洁清晰,书籍资源丰富。4.亚马逊图书书籍...

最好免费观看高清电影(播放免费的最好看的电影)

在目前的网上选择中,IMDb(互联网电影数据库)被认为是最全的电影网站之一。这个网站提供了各种类型的电影和电视节目的海量信息,包括剧情介绍、演员表、评价、评论等。其还提供了有关电影制作背后的详细信息,...

孤单枪手2简体中文版(孤单枪手2简体中文版官方下载)

要将《孤胆枪手2》游戏的征兵秘籍切换为中文,您可以按照以下步骤进行操作:首先,打开游戏设置选项,通常可以在游戏主菜单或游戏内部找到。然后,寻找语言选项或界面选项,点击进入。在语言选项中,选择中文作为游...

取消回复欢迎 发表评论: