惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Schneier on Security
A
Arctic Wolf
S
Security Affairs
O
OpenAI News
SecWiki News
SecWiki News
TaoSecurity Blog
TaoSecurity Blog
H
Heimdal Security Blog
T
Threat Research - Cisco Blogs
Hacker News: Ask HN
Hacker News: Ask HN
N
News | PayPal Newsroom
Google Online Security Blog
Google Online Security Blog
C
Cisco Blogs
The Hacker News
The Hacker News
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
CXSECURITY Database RSS Feed - CXSecurity.com
P
Privacy International News Feed
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
T
Tenable Blog
T
The Exploit Database - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Spread Privacy
Spread Privacy
人人都是产品经理
人人都是产品经理
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V2EX - 技术
V2EX - 技术
L
LINUX DO - 最新话题
The GitHub Blog
The GitHub Blog
博客园 - 三生石上(FineUI控件)
T
The Blog of Author Tim Ferriss
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
V
Visual Studio Blog
The Cloudflare Blog
N
News and Events Feed by Topic
量子位
Google DeepMind News
Google DeepMind News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
Stack Overflow Blog
Stack Overflow Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Attack and Defense Labs
Attack and Defense Labs
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Hacker News - Newest:
Hacker News - Newest: "LLM"
Apple Machine Learning Research
Apple Machine Learning Research
The Register - Security
The Register - Security
Microsoft Security Blog
Microsoft Security Blog
Know Your Adversary
Know Your Adversary
Webroot Blog
Webroot Blog

少数派

派早报:Google 发布 Fitbit Air 等 - 少数派 「新人报到」確認需求,再開始 - 少数派 从 SOLO 独立开发者社区,我看到了越来越多开发者开始做自己的产品 - 少数派 我怎么管理那些"不常做,但总会忘"的生活事项 - 少数派 人形机器人量产元年,数据才是具身智能的“生死线” - 少数派 BuhoLaunchpad 高度还原 Mac 启动台:开发历程与思考 - 少数派 五年陪伴依然不舍,DIY 换壳后让罗技 MX Master 3 继续服役 - 少数派 新玩意 240|少数派的编辑们最近买了啥? - 少数派 一日一技|为什么你应该关闭 iOS 的键盘声音 - 少数派 我做了个插件和 Skills,一键提取任何网站的设计规范 Design.md - 少数派 住在三四线城市的你,该开始录播客了 - 少数派 甘南秘境,大白高国 - 少数派 AI的审美:谁让把我变成川内倫子 - 少数派 返工怎能不烦恼,打工人片单总有一部是你的「嘴替」 - 少数派 为了让「上厕所」更健康,我做了一个小工具 - 少数派 AI + Skill,能够让生成的文章去除 AI 味吗? - 少数派 新玩意|韶音OpenDots ONE 耳夹式耳机 - 少数派 《美满》| 在每一个春天的晚上相爱(362) - 少数派 新玩意|优篮子 PS01 MagSnap 磁吸支架 - 少数派 自我整合手记 | 我开始早睡了:用稳定规则,为自由托底 - 少数派 用龙虾(OpenClaw)两个多月,我最深的12个体会 - 少数派 听歌时间到,12 张你可能错过的 2025 华语乐坛好专辑 - 少数派 承诺能追吗 - 少数派 macOS 26启动台没了? 我做了个不一样的App启动器 - Keboard - 少数派 《四海为家的人》| INTJ对话INTJ(361) - 少数派 你发过的那些黑历史,是时候一次清干净了 - 少数派 新玩意:安安静静玩,越玩越专注:计客密码机 - 少数派 iPad 用户首次体验 Android 平板:vivo Pad6 Pro - 少数派 数据逻辑强 - 少数派 极北行+ | 一路向北,探访日本至北之地 | 001 - 少数派 万字剖析:千问App深度体验报告(2026) - 少数派 在2026年,如何真正防止别人抄袭你的作品 - 少数派 怎么用 50 块搭个 AI 语音助手?我踩了 3 天坑 - 少数派 YeeroAI:让 AI 对话真正成为知识管理的一部分 - 少数派 爬泰山 - 少数派 「旅图显影」 App 更新:这次,我们补上了一点「手感」 - 少数派 假期出门太折磨?我的 23 条经验帮你规划惬意旅行 - 少数派 工作流会变吗 - 少数派 Claude Opus 4.6 怎么用最省钱?我测了 5 种方案 - 少数派 GPT Image 2 让图文并茂不再稀罕 - 少数派 用户侧出发——什么是AI,我要不要学习? - 少数派 找片、转存、整理、播放一条龙!让你的付费网盘值回票价 - 少数派 欢迎试用!日课一问2.0插件 - 少数派 自己做的MDeditor,原本想购买 Typora 试了两次支付不成功,干脆自己做一个 - 少数派 vibe coding了一个 3MB 的小工具,让 ~/Downloads 彻底告别混乱 - 少数派 因为受不了 Mac 的风扇策略,我做了一个风扇控制工具 - 少数派 别只怪模型 - 少数派 Warp 终端的 AI 功能怎么用?我测了一周的体验 - 少数派 AI 写代码老是出 bug?这 5 个配置我后悔没早知道 - 少数派 「新玩意」苹果出相机可能就这样:Sigma BF + 45mm F2.8 DG Contemporary - 少数派 一个面向2030年的AI操作系统是什么样子的:浅谈cola这款有灵魂的Agent - 少数派 别只看写代码 - 少数派 每天解决10个问题,还是一口气攻坚解决400个? - 少数派 AI 交易机器人怎么搭?我用 Claude 跑了一周实盘 - 少数派 Maptoposter Online:把你爱的城市画成艺术海报 - 少数派 Function Calling 怎么用?我测了 3 个模型发现差距真大 - 少数派 Legend Talk:我做了个 AI 圆桌,让 160 位思想家围着你的问题转 - 少数派 如何找到自己的蓝方?在小县城寻找压力测试 - 少数派 语音输入与软件接口|2026年聊AI时,我们都聊些什么(上) - 少数派 混动已经卖爆,纯电又来补刀——钛7闪充版简直“不讲武德” - 少数派 本月玩什么|朋友收藏、识质存在、沙罗周期 - 少数派 为什么要每天坚持输出? - 少数派 Claude API 挂了好几个小时,你的项目有备用方案吗? - 少数派 Function Calling 没你想的复杂——我用它做了个有点用的工具 - 少数派 登录系统立即播放视频或者图片音乐的软件 - 少数派 我为什么创建 FlipHTML5 下载工具 - 少数派 残局没电?多品牌外设电量统一管理软件EasyBluetooth已支持RTSS游戏内显示以及AIDA64 - 少数派 前往通义路的路 - 少数派 太好看了,媲美Sun的个人导航页,NAS部署星云门户 - 少数派 乌黑嘴唇“一键检测”上线了 - 少数派 派早报:Claude AI 接入多个创意软件生态、FILCO 生产方接手品牌等 - 少数派 【更新】BearCLI、Claude 连接器与 MCP 服务器 - 少数派 记了上千条流水,还是看不懂财务?我做了一个让 AI 读懂账本的工作台 - 少数派 MINI R56 升级原厂 Sport 模式 - 少数派 新玩意 | 一棵柠檬树(仿真版) - 少数派 Momenta的“物理AI”野望,需迈过“含摩量”这道关 - 少数派 网页直接投屏控制手机!NAS一键部署PandaScrcpy,流畅丝滑可远程。 - 少数派 众测|邀你一同探索随身 AI 硬件入口 YoooClaw C·ONE - 少数派 2050大会:分享时间是真诚 参会记 - 少数派 iPad 赋能电影创作:国内首部宣纸手绘长片《燃比娃》的幕后故事 - 少数派 AI的审美:我用 8 个大模型给 100 张旅行照片打分 - 少数派 普通人如何破圈?去参加一个本地协会 - 少数派 把极空间的图标全换了,主题DIY全攻略打造你的专属NAS桌面 - 少数派 电子便签墙,帮你实现便签自由 - 少数派 我如何用三个 CLI 工具取代文档创建需求 - 少数派 原来真的有人可以玩一辈子 - 少数派 社区速递 139 | 派友热议三月买了啥、复古单反尼康 Df 体验 - 少数派 06 作品的赏析与评价 - 少数派 TDS REVIEW|索尼 WF-1000XM6 降噪真无线耳机体验 - 少数派 35.98万起售的第二代腾势D9,我看重的不是堆料,而是不凑合 - 少数派 鼠须管 Squirrel 皮肤配置指北 - 少数派 从watch ultra2换到redmi watch6 - 少数派 派早报:阿里巴巴发布视频生成模型 HappyHorse 1.0 等 - 少数派 别迷信1M - 少数派 家人们天塌了!网盘“大封杀”,多个渠道多条路,NAS部署PanHub - 少数派 AI与人勾心斗角!NAS一键部署AI狼人杀,假日休闲必备。 - 少数派 电商必备!Comfyui工作流批量生图插件,一次生成12张!支持Nano banana pro模型 - 少数派 Comfyui工作流配置Gpt-image-2模型教程,0.03/张 - 少数派 OpenClaw第三方APi怎么配置?可使用Gpt-image-2模型 - 少数派 会员社区话题精选 Ep. 103 - 少数派
20. 异常处理 - 少数派
2023-08-16 · via 少数派
cover

Hi,大家好。我是茶桁。

在我们日常使用Python或者其他编程语言的时候,不可避免的都会出现报错和异常。那么,我们今天就来谈谈异常。

什么是异常?

异常异常,根据名字简单理解,那就是非正常,也就是没有达到预期目标。

异常呢,其实就是一个事件,并且这个异常事件在程序的运行过程中出现,会影响程序的正常执行。而一般来说,异常被分为两种:

  1. 语法错误导致的异常
  2. 逻辑错误导致的异常

比如:

varlist = [1, 2, 3]
print(varlist[3])

---
IndexError: list index out of range

这个时候,系统抛出了异常,提示我们列表索引超出范畴。

这里我们需要知道,「异常」在Python中实际上也是一个对象,表示一个错误。当我们的程序无法继续正常进行时,就会被抛出。

我们来完整的看看这个报错信息:

---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[2], line 2
      1 varlist = [1, 2, 3]
----> 2 print(varlist[3])

IndexError: list index out of range

Python在遇到异常之后,首先会给出一个「错误回溯」, 然后给出具体哪一句代码出现了问题。

然后在最后给出异常分类和解释。那么IndexError告知我们,这是一个「索引错误」,并且给出了具体的描述「列出索引超出范围」。其中IndexError是我们的异常类, list index out of range是我们的异常信息。

在程序运行过程中,会出现各种各样的异常类,常见标准异常类,我放在最下面作为一个附录。

如何处理异常

可预知

如果错误发生的情况是我们可以预知的,那么就可以使用流程控制进行预防处理。比如,两个数字的运算,其中一个不是数字,运算就会出错,这个时候就可以判断来预防:

n2 = '3'
if isinstance(n2, int):
    res = 10+n2
    print(res)
else:
    print('非整型。')

---
非整形

在这一段代码中,我们使用isinstance方法来检测第一个参数是否是第二个参数的所属类型。这是一个用来检测的方法,返回True或者False。那我们在if中,只有真才会打印结果,假则会打印另外一则消息。

有些小伙伴会想,那既然知道不是整型就会出错,那前面限制传如整型不就好了,干嘛还要费劲去做非整判断。

你要知道,很多时候一个程序的编写和维护并不是单一一个人来做的,即便是一个人在做,也不能完全保证自己某个地方埋下了隐患。那么在每一段代码中,我们对可能预知的情况做妥善的预防是必须的。

不可预知

那可预知的情况我们避免了,可是在我们编写代码的时候,更多的情况是我们自己都不知道我们到底埋了什么雷,哪一段没有遵循规则或者逻辑。那这种情况就是不可预知的。

对于这种不可预知的情况我们该怎么办呢?我们又没办法预先判断。那这种情况下,我们可以使用try...except...语句,在错误发生时进行处理。相关语法如下:

try:
    可能发生异常错误的代码
except:
    如果发生异常这进入except代码块进行处理

异常被捕获之后程序继续向下执行

我们来看个示例,比如我们之前做过的一个注册、登录练习。其中我们有一段代码是要去读取列表中的所有用户。之前我们的练习中,有提到过文件不存在的情况,所以我们使用了a+的方法,当文件不存在的时候,就新建。

那么现在,我们假设我们就用了r的方法,当文件不存在的时候,一定会报错对吧?这个时候,我们可以使用两种方式来进行处理。

第一种方式,就可以在读取前先判断当前文件是否存在。

第二种方式,就可以使用try...except...在错误发生的时候进行处理。

那么这里,我们用第二种方式来做一下处理:

# 假设我们读取的文件不存在,会发生错误
try:
    with open('./data/user5.txt', 'r') as fp:
        res = fp.read()
    print(res)
except:
    print('文件不存在。')

print('程序继续运行...')

---
文件不存在。
程序继续运行...

可以看到,我们准确的捕获了错误,并且之后程序仍然继续往后执行了。

⚠️ try...except... 是在错误发生后进行处理,并不是提前判断。也就是说,错误其实还是发生了。这和if实际上有根本性的区别。

try...except... 详解

首先,我们认识try...except的一个特性,就是它可以处理指定的异常,如果引发了非指定的异常,则无法处理。比如,我们下面人为制造一个异常:

s1 = 'hello'
int(s1)

---
ValueError: invalid literal for int() with base 10: 'hello'

可以看到,我们这一段代码引发了一个ValueError异常。

现在我们来捕获一下, 但是这次,我们为这个异常指定一个异常类再来看看,先看看正常状态下:

try:
    s1 = 'hello'
    int(s1)
except:
    print('程序错误。')
    
---
程序错误。

接着我们来看指定异常之后:

try:
    s1 = 'hello'
    int(s1)
except IndexError as e:
    print('程序错误。')
    
---
ValueError: invalid literal for int() with base 10: 'hello'

这里我们指定了一个IndexError的异常类,显然我们之前看到了,程序报错是ValueError异常类,两者并不匹配。所以最后依然还是报错。

那么之前我们谈到过标准的异常类,并且也知道异常实际上也就是一个对象。而我们平时在使用的时候,except实际上就是去这个「标准的异常类」的列表里去查找,如果没有对应的异常类,它依然是无法捕获的。不过大部分时候,我们基本不会遇到标准异常类之外的异常。而这种处理指定的异常类的特性,平时也可以被我们使用。

其中一个使用方式,就是进行多分支处理异常类,不同的异常可以走不通的except进行处理:

s1 = 'hello'
try:
    s1[5] # IndexError
except IndexError as e:
    print('这里是IndexError', e)
except KeyError as e:
    print('这里是KeyError', e)
except ValueError as e:
    print('这里是ValueError', e)
    
---
这里是IndexError string index out of range

是不是和if...elif的分支形式很像?

让我们继续,在我们说指定的异常类中,实际上会有一个万能的通用异常类。那就是Exception

s1 = 'world'
try:
    int(s1)
except Exception as e:
    print('Exception ===',e)
    
---
Exception === invalid literal for int() with base 10: 'world'

基本上所有的异常,都可以走到这个异常类。在这段代码中,我们之前记得int(s1)是属于一个ValueError, 但是我们使用Exception依然可以获取到这个错误。可是如果这两种异常类同时被指定的情况下会如何?

s1 = 'world'
try:
    int(s1)
except Exception as e:
    print('Exception ===',e)
except ValueError as e:
    print('ValueError ===', e)
    
---
Exception === invalid literal for int() with base 10: 'world'

我们看到,就是按照程序的从上至下的顺序在执行。

所以,其实我们可以这样理解,当我们进行多分支异常类+通用异常类的时候,Exception是最后的一个保底。

s1 = 'hello'
try:
    # int(s1) # ValueError
    s1[5]    # IndexError
except IndexError as e:
    print('IndexError',e)
except KeyError as e:
    print('KeyError',e)
except ValueError as e:
    print('ValueError',e)
except Exception as e:
    print('Exception',e)
    
---
IndexError string index out of range

除此之外,try...except是支持else的,当try里的代码顺利执行没有捕获到任何错误之后,还可以走到else之中额外执行分支内的代码:

s1 = 'hello'
try:
    str(s1)
    print(s1)
except IndexError as e:
    print('IndexError',e)
except ValueError as e:
    print('ValueError',e)
except Exception as e:
    print('Exception',e)
else:
    print('try代码块中没有引发异常时,执行')
    
---
hello
try代码块中没有引发异常时,执行

我们再来了解一下finally, 这个方法是无论是否引发异常都会执行。通常情况下用于执行一些清理工作:

s1 = 'hello'
try:
    int(s1)
    print('如果前面的代码引发了异常,这个代码块将不在继续执行。。')
except IndexError as e:
    print('IndexError',e)
except ValueError as e:
    print('ValueError',e)
except Exception as e:
    print('Exception',e)
else:
    print('try代码块中没有引发异常时,执行')
finally:
    print('无论是否引发了异常,都会执行这个代码块')

print('如果上面的代码有异常并且进行了处理,那么后面的代码将继续执行')

---
ValueError invalid literal for int() with base 10: 'hello'
无论是否引发了异常,都会执行这个代码块
如果上面的代码有异常并且进行了处理,那么后面的代码将继续执行

这段代码中,我们引发了一个异常,也被捕获了。但是依然执行了finally内的代码,并且也未影响程序继续往后执行。

在我们平常写代码的过程中还有一种情况,就是我们需要自己制作一个异常信息,然后抛出。这个时候,我们需要用raise, 来主动抛出异常。

try:
    raise Exception('发生错误')
except Exception as e:
    print('Exception', e)
    
---
Exception 发生错误

除了上述的异常处理之外,其实还有另外一种方式,是直接判断逻辑是否成立,不成立抛出AssertionError错误。就是使用assert进行断言。它在表达式错误的时候,会直接抛出AssertionError错误,如果表达式正确,这什么都不做。

assert 2 > 3

---
AssertionError: 

自定义异常处理类

虽然系统已经给到了很多异常处理的方式,而我们在平时开发中也会经常的使用。但是实际上,很多时候我们都需要一些自己的处理要求。比如说,当异常出现的时候,我们要将异常信息写入日志,在日后我们从日志里查看日常信息或者做数据分析,就是我们最常使用的。

那我们接下来看看,如果做一个异常处理的自定义开发:

再最开始,我们需要归纳一下,我们到底要保存怎样一个格式:

# 日志的基本格式:
- 日期时间, 异常的级别
- 异常信息:引发的异常类别,异常的信息,文件及行号。

在确定了日志格式后,我们可以进入开发了,首先我们需要导入两个所需的库

# 先导入所需模块
import traceback
import logging

让我们先来人为创建一个日常,并用try语句来捕获它:

 int('aaa')
  
---
ValueError: invalid literal for int() with base 10: 'aaa'

这句代码报了一个ValueError异常类。

try:
    int('aaa')
except:
    print('在此进行异常的处理')
    
---
在此进行异常的处理

没问题,我们捕获了异常并且正确的进入了except。那么,我们可以通过traceback模块来获取异常信息, 替换一下打印信息我们来查看一下。

try:
    int('aaa')
except:
    # 通过traceback获取异常信息
    errormsg = traceback.format_exc()
    print(errormsg)
    
---
Traceback (most recent call last):
  File "/var/folders/h4/7cr1cmpn7v5b3x20_9wz8m740000gn/T/ipykernel_39689/2534911191.py", line 2, in <module>
    int('aaa')
ValueError: invalid literal for int() with base 10: 'aaa'

接下来,就轮到logging模块了。该模块定义了实现用于应用程序和库的灵活事件日志记录系统的函数和类。

logging.basicConfig(
    filename = './data/error.log', # 日志存储的文件及目录
    format='%(asctime)s %(levelname)s \n %(message)s', # 格式化存储的日志格式
    datefmt = '%Y-%m-%d %H:%M:%S'
)

在定义了logging的基本信息之后,我们就可以定义一下将刚才的errormsg写入日志了:

# 写入日志
logging.error(traceback.format_exc())

那么我们完善一下整个代码就是这样:

logging.basicConfig(
    filename = './data/error.log', # 日志存储的文件及目录
    format='%(asctime)s %(levelname)s \n %(message)s', # 格式化存储的日志格式
    datefmt = '%Y-%m-%d %H:%M:%S'
)

# 写入日志
logging.error(traceback.format_exc())

我们需要在异常出发的时候,将错误写入到日志内。那么需要将这段代码放到except中。可是我们总不能每次都写这么长一段代码,那怎么办呢?嗯,没错,我们需要封装一个函数用于多次调用。

def Myexception():
    # logging的基本配置
    logging.basicConfig(
        filename = './data/error.log', # 日志存储的文件及目录
        format='%(asctime)s %(levelname)s \n %(message)s', # 格式化存储的日志格式
        datefmt = '%Y-%m-%d %H:%M:%S'
    )

    # 写入日志
    logging.error(traceback.format_exc())

# 使用自定义异常处理类
try:
    int('bb')
except:
    print('在此处进行异常的处理')
    Myexception() # 在异常处理的代码块中去调用自定义异常类

然后我们将导入库的方法也写进去,这样在我们需要的时候才会进行导入,顺便,我们将这个函数封装成一个类。就便于更多的文件调用:

# 自定义异常日志处理类
class Myexception():
    def __init__(self):
        import traceback
        import logging

        # logging的基本配置
        logging.basicConfig(
            filename='./error.log',# 日志存储的文件及目录
            format='%(asctime)s  %(levelname)s \n %(message)s',# 格式化存储的日志格式
            datefmt='%Y-%m-%d %H:%M:%S'
        )
        # 写入日志
        logging.error(traceback.format_exc())

# 使用自定义异常处理类
try:
    int('bb')
except:
    print('在此处进行异常的处理')
    Myexception() # 在异常处理的代码块中去调用自定义异常类

这样,一个自定义的获取异常之后写入日常的类就定义好了,我们可以在任意地方导入并调用这个类方法,以便获取以及日后查看整个程序中的异常。

附录

标准的异常类

异常名称描述
BaseException所有异常的基类
SystemExit解释器请求退出
KeyboardInterrupt用户中断执行(通常是输入^C)
Exception常规错误的基类
StopIteration迭代器没有更多的值
GeneratorExit生成器(generator)发生异常来通知退出
StandardError所有的内建标准异常的基类
ArithmeticError所有数值计算错误的基类
FloatingPointError浮点计算错误
OverflowError数值运算超出最大限制
ZeroDivisionError除(或取模)零 (所有数据类型)
AssertionError断言语句失败
AttributeError对象没有这个属性
EOFError没有内建输入,到达EOF 标记
EnvironmentError操作系统错误的基类
IOError输入/输出操作失败
OSError操作系统错误
WindowsError系统调用失败
ImportError导入模块/对象失败
LookupError无效数据查询的基类
IndexError序列中没有此索引(index)
KeyError映射中没有这个键
MemoryError内存溢出错误(对于Python 解释器不是致命的)
NameError未声明/初始化对象 (没有属性)
UnboundLocalError访问未初始化的本地变量
ReferenceError弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError一般的运行时错误
NotImplementedError尚未实现的方法
SyntaxErrorPython 语法错误
IndentationError缩进错误
TabErrorTab 和空格混用
SystemError一般的解释器系统错误
TypeError对类型无效的操作
ValueError传入无效的参数
UnicodeErrorUnicode 相关的错误
UnicodeDecodeErrorUnicode 解码时的错误
UnicodeEncodeErrorUnicode 编码时错误
UnicodeTranslateErrorUnicode 转换时错误
Warning警告的基类
DeprecationWarning关于被弃用的特征的警告
FutureWarning关于构造将来语义会有改变的警告
OverflowWarning旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning关于特性将会被废弃的警告
RuntimeWarning可疑的运行时行为(runtime behavior)的警告
SyntaxWarning可疑的语法的警告
UserWarning用户代码生成的警告

那么,这节课到这里也就结束了。各位小伙伴,下去以后记得勤加练习。下课。