Python——异常处理机制
Python 异常处理机制
- Python异常与异常处理机制
- 针对 Traceback 的解读
- try-except-else-finally
- except语句
- except语句的机制
- 在 except 语句中引用当前被处理的 Python 异常
- finally语句
- finally语句执行后才能抛出未被处理的异常
- finally中执行return会导致异常丢失
- raise 语句
- raise 语句以及异常对象
- raise…from 语句
- Python 异常的基类 BaseException
Python异常与异常处理机制
Python使用称为异常的特殊对象来管理程序执行期间发生的错误(Python中一切皆对象,包括异常也是对象)。每当发生程序错误,都会创建一个异常对象。如果编写了处理该异常的代码,程序将继续运行;但是如果未编写代码对异常进行处理,程序将停止并显示traceback,其中包含有关异常的报告
异常处理是编程语言或计算机硬件里的一种机制,用于处理软件或信息系统中出现的异常状况,即超出程序正常执行流程的某些特殊条件。异常处理机制是使用 try-except 代码块处理异常,try-except 代码块让Python执行指定的操作,同时告诉Python发生异常时怎么办。使用try-except 代码块时,即便出现异常,程序也将继续运行,同时显示你编写的友好的错误消息,而不是令用户迷惑的traceback
Python提供了两个非常重要的功能来处理程序在运行中出现的异常和错误。经常使用的是try…except语句,拓展一下就是try-except-else-finally,另一个是断言,即assert
针对 Traceback 的解读
Traceback 是 Python 错误信息的报告,当你的程序导致异常时,Python 将打印 Traceback 以帮助你知道哪里出错了。虽然 Python 的 Traceback 提示信息看着挺复杂,但是里面存在丰富的信息,可以帮助你诊断和修复代码中引发异常的原因,以及定位到具体哪个文件的哪行代码出现的错误,这样有助于我们编写对应的异常处理代码来捕获异常,并给出合适的错误提示信息。所以说学会看懂 Traceback 信息是非常重要的
下面给出一个案例进行分析,这是一种导致Python引发异常的简单错误:除0
# calculate.py文件的内容
def divide(a, b): # 进行除法运算的函数return a / b# main.py文件的内容
from calculate import dividedivide(5, 0)# 抛出异常:
"""
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 3, in <module>divide(5, 0)File "C:\编程\Python代码\test\calculate.py", line 2, in dividereturn a / b
ZeroDivisionError: division by zero
"""
- 错误输出的最后一行一般会告诉你引发了什么类型的异常,以及关于该异常的一些相关信息,所以看错误信息的最后一行就能获知到错误的原因
- 在上述 traceback 中,最后一行指出的错误 ZeroDivisionError 就是一个异常对象,并且给出了具体的描述 division by zero,即表示因为除0,导致程序抛出该异常
- 错误输出的前面几行的阅读顺序应该是由下而上的,因为越往上,离抛出异常的实际位置越远,越难定位到抛出异常的代码
- 这一部分要每连续两行为一组进行阅读。其中每组的第1行会告诉你是在哪个文件的、哪个函数的、哪一行出错了,也就是会更直接的告诉你错误发生的位置;每组的第2行会把报错的那一行代码显示出来
- 比如在程序里A函数调用了B函数,然后B函数调用了C函数,而C函数报错了,那么 traceback 中的前几行从下至上的顺序来看,会先显示C函数的信息,再显示B函数的信息,再显示A函数的信息,而且每一个函数的信息都是按两行来组织的,其中第1行展示位置,第2行展示代码
- 在上述 traceback 中,前面几行中的最后一行定位的位置为位于 calculate.py 文件中的第2行,并且位于 divide 函数代码块中,具体抛出异常的代码为"return a / b"
- 然后我们看上一行,定位的位置为位于 main.py 文件中的第3行,并且位于引入模块的代码中,具体抛出异常的代码为"divide(5, 0)"
- 最上面第一行的内容是固定不变的,始终Traceback (most recent call last)”,可以忽略
try-except-else-finally
- try:正常情况下,程序计划执行的语句
- except:程序异常时执行的语句
- else:程序无异常即try段代码正常执行后会执行该语句
- 当try语句的相关代码中的return,continue或break语句被执行时,else语句将被忽略
- finally:不管有没有异常,都会执行的语句
- 具体来说,当try,except或else语句的相关代码中存在某些跳转语句时,比如break,continue和return,与finally语句相关的代码将在这些跳转语句执行之前被执行
- 在处理 Python 异常的过程中,一些代码需要始终被执行,无论是否有 Python 异常被抛出,或 Python 异常是否被处理。使用finally语句可以达成上述目标,该语句之后的代码通常与清理工作有关,比如,关闭打开的文件
运行逻辑1:首先运行try中的代码块,当出现异常时,终止try中代码块的执行,立即执行except中的代码块,最后执行finally中的代码块
try:print('输出:我是try1')a = 5 / 0print('输出:我是try2')except :print('输出:我是except')else :print('输出:我是else')finally :print('输出:我是finally')# 输出结果:
"""
输出:我是try1
输出:我是except
输出:我是finally
"""
运行逻辑2:首先运行try中的代码块,当执行完毕后,代码始终没有抛出异常,继续执行else中的代码块,最后执行finally中的代码块
try:print('输出:我是try1')a = 5 / 1print('输出:我是try2')except :print('输出:我是except')else :print('输出:我是else')finally :print('输出:我是finally')# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:我是else
输出:我是finally
"""
运行逻辑3:函数中,如果finally语句的相关代码中包含了return语句,那么该return语句所返回的值(包括空值None),将取代try,except或else语句相关代码中的返回值
因为finally中的代码块在设定上必须执行:
- 在try中的代码块return之前,会执行finally中的语句,try中的return被忽略了,最终返回的值是finally中return值
- try中的代码块没有return语句,执行完毕后,会继续执行else中的语句,在else中的代码块return之前,执行finally中的语句,else中的return被忽略了,最终返回的值是finally中return值
- try中的代码块中抛出异常,被except捕获,在except中的代码块return之前,执行finally中的语句,except中的return被忽略了,最终返回的值是finally中return值
def test():try:print('输出:我是try1')a = 5 / 0print('输出:我是try2')return 1except :print('输出:我是except1')return 2print('输出:我是except2')else :print('输出:我是else')return 3finally :print('输出:finally')return 4num = test()
print(num)# 输出结果:
"""
输出:我是try1
输出:我是except1
输出:finally
4
"""def test():try:print('输出:我是try1')a = 5 / 1print('输出:我是try2')return 1except :print('输出:我是except')return 2else :print('输出:我是else')return 3finally :print('输出:finally')return 4num = test()
print(num)# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:finally
4
"""def test():try:print('输出:我是try1')a = 5 / 1print('输出:我是try2')# return 1except :print('输出:我是except')return 2else :print('输出:我是else1')return 3print('输出:我是else2')finally :print('输出:finally')return 4num = test()
print(num)# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:我是else1
输出:finally
4
"""
运行逻辑4:函数中,finally中不存在return,并且try中代码块没有抛出异常,那么按照 运行逻辑2,函数返回的是try或者else代码中先出现的那个return值
因为代码中程序正常运行,不一定要执行else中的代码块,如果try中return直接结束函数执行了,那么就不会执行else中的代码块
def test():try:print('输出:我是try1')a = 5 / 1print('输出:我是try2')return 1except :print('输出:我是except')return 2else :print('输出:我是else')return 3finally : # finally中不存在return语句print('输出:finally')# return 4 num = test()
print(num)# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:finally
1
"""def test():try:print('输出:我是try1')a = 5 / 1print('输出:我是try2')# return 1except :print('输出:我是except')return 2else :print('输出:我是else')return 3finally : # finally中不存在return语句print('输出:finally')# return 4 num = test()
print(num)# 输出结果:
"""
输出:我是try1
输出:我是try2
输出:我是else
输出:finally
3
"""
运行逻辑5:函数中,finally中不存在return,并且try中代码块产生异常,那么按照 运行逻辑1,函数返回的是except代码中的那个return值
因为代码中程序抛出异常,必须执行except中的代码块
def test():try:print('输出:我是try1')a = 5 / 0print('输出:我是try2')return 1except :print('输出:我是except')return 2else :print('输出:我是else')return 3finally : # finally中不存在return语句print('输出:finally')# return 4 num = test()
print(num)# 输出结果:
"""
输出:我是try1
输出:我是except
输出:finally
2
"""
except语句
except语句的机制
每一个try语句,都必须至少有一个except语句,除非存在 finally 语句
- 一般一个try语句后面都需要存在至少一个except语句,但是使用 finally 语句后 except 语句将成为可选的,try语句之后可以没有任何except语句
try:print("No Error")# 抛出异常:SyntaxError: unexpected EOF while parsingtry:5/0# 抛出异常:SyntaxError: unexpected EOF while parsingtry:print("No Error")finally:print("Something must be done")# 输出结果:
"""
No Error
Something must be done
"""try:5/0finally:print("Something must be done")# 输出结果:
"""
Something must be done
Traceback (most recent call last):File "C:\编程\Python代码\test\test.py", line 3, in <module>5/0
ZeroDivisionError: division by zero
"""
使用 else 语句的前提是至少拥有一个 except 语句
- 如果要使用else语句来处理没有 Python 异常被引发的情况,那么在try语句之后,必须至少存在一个except语句
try:print("No Error")else:print("must have except")finally:print("Something must be done")# 抛出异常:SyntaxError: invalid syntaxtry:print("No Error")except:print("waiting for error")else:print("must have except")finally:print("Something must be done")# 输出结果:
"""
No Error
must have except
Something must be done
"""
一个try…except语句中可以拥有多个except语句,都是最多只有一个 except 语句能与被抛出 Python 异常匹配
- 如果try…except语句拥有多个except语句,那么与 Python 的 if 语句类似,他们会按照先后顺序进行匹配,当某一个except语句与被抛出的 Python 异常匹配时,其余的except语句将被忽略
try:5/0except IndexError as e: # 无法捕获除0异常print("IndexError")except ZeroDivisionError as e: # 可以捕获除0异常print("ZeroDivisionError1")except ZeroDivisionError as e: # 可以捕获除0异常print("ZeroDivisionError2")except BaseException as e: # 可以捕获除0异常print("BaseException")# 输出结果:ZeroDivisionError1try:5/0except IndexError as e: # 无法捕获除0异常print("IndexError")except BaseException as e: # 可以捕获除0异常print("BaseException")except ZeroDivisionError as e: # 可以捕获除0异常print("ZeroDivisionError1")except ZeroDivisionError as e: # 可以捕获除0异常print("ZeroDivisionError2")# 输出结果:BaseException
except可以处理一个专门的异常,也可以处理包含在元组中的一组异常
- 可以将多个异常类型放在一个括号中,通过逗号分隔。当try块引发其中任何一个异常时,程序都将跳转到该except块,处理这个异常
try:5 / 0except (IndexError, ZeroDivisionError) as e: # 可以捕获除0异常print("IndexError or ZeroDivisionError")except BaseException as e: # 可以捕获除0异常print("ZeroDivisionError1")# 输出结果:IndexError or ZeroDivisionError
如果except后没有指定异常类型,则默认捕获所有的异常
- 此时捕获异常范围为BaseException(后面会提到)
- 这样的没有指定异常类型的 except 语句要求必须是最后一个 except 语句,否则程序报错
- 原因很简单,如果它位于其他except语句之前,那么一些except语句将失去被执行的可能
try:5 / 0except: # 可以捕获所有异常print("捕获到异常")# 输出结果:捕获到异常
与所有 except 语句均不匹配的 Python 异常将被重新抛出
- 如果一个 Python 异常被引发,并且与所有的except语句均不匹配,那么该异常将作为未处理的 Python 异常被重新抛出,这可能导致整个程序因此结束执行(当然,finally中的代码块依旧会被执行)
try:5/0except IndexError as e: # 无法捕获除0异常print("IndexError")except KeyError as e: # 无法捕获除0异常print("KeyError")except ValueError as e: # 无法捕获除0异常print("ValueError")finally:print('输出:finally')# 抛出异常:
"""
输出:finally
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 2, in <module>5/0
ZeroDivisionError: division by zero
"""
在 except 语句中引用当前被处理的 Python 异常
在except语句中,使用as关键字可以指定一个与被处理异常绑定(指向异常对象)的标识符(可将其简单的视为 Python 变量),即可通过该标识符在except语句相关的代码中访问被处理的 Python 异常
此外,在 3.11 或更高版本中,通过sys模块的exception函数,同样可在except语句相关的代码中访问当前被处理的 Python 异常
- 异常对象的常用属性
- args:包含有关异常的错误编号和异常的描述的元组
- strerror:异常的描述
- errno:与异常的错误编号
try:open("no_exit_file.txt", "r")except FileNotFoundError as e: # 可以捕获除0异常print("异常对象:", e)print("异常类型:", type(e))# 异常对象的常用属性print("异常信息: ", e.args) # 该属性返回异常的错误编号和描述print("异常描述: ", e.strerror) # 该属性返回异常的描述print("错误号: ", e.errno) # 该属性返回异常的错误编号# 输出结果:
"""
异常对象: [Errno 2] No such file or directory: 'no_exit_file.txt'
异常类型: <class 'FileNotFoundError'>
异常信息: (2, 'No such file or directory')
异常描述: No such file or directory
错误号: 2
"""
except 语句会删除使用 as 关键字与 Python 异常绑定的标识符
- 如果在某个except语句中使用了as关键字,那么as关键字指定的标识符,将在该except语句的相关代码执行完毕时被删除。这意味着标识符仅在except语句中保持其正确性,他不应该与同一命名空间的其他标识符重复,以避免一些不必要的错误
try:open("no_exit_file.txt", "r")except FileNotFoundError as e: # 可以捕获除0异常print("异常对象:", e)print("异常类型:", type(e))print(e)# 输出结果:
"""
异常对象: [Errno 2] No such file or directory: 'no_exit_file.txt'
异常类型: <class 'FileNotFoundError'>
Traceback (most recent call last):File "C:\编程\Python代码\test\test.py", line 9, in <module>print(e)
NameError: name 'e' is not defined
"""
finally语句
finally语句执行后才能抛出未被处理的异常
当try,except或else语句的相关代码引发不能被处理的 Python 异常时,这些异常不会被立即抛出,他们需要等待finally语句的相关代码的执行
try:5/0except IndexError as e: # 无法捕获除0异常print("IndexError")except KeyError as e: # 无法捕获除0异常print("KeyError")except ValueError as e: # 无法捕获除0异常print("ValueError")finally:print('输出:finally')# 抛出异常:
"""
输出:finally
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 2, in <module>5/0
ZeroDivisionError: division by zero
"""try:5 / 0except ZeroDivisionError as e:print("ZeroDivisionError异常被捕获")raise efinally:print('输出:finally')
# 输出结果:
"""
ZeroDivisionError异常被捕获
输出:finally
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 6, in <module>raise eFile "C:\编程\Python代码\test\main.py", line 2, in <module>5 / 0
ZeroDivisionError: division by zero
"""try:5 / 1except ZeroDivisionError as e:print("ZeroDivisionError异常被捕获")else:print('输出:else')raise ZeroDivisionError("重新抛出的ZeroDivisionError")finally:print('输出:finally')
# 输出结果:
"""
输出:else
输出:finally
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 9, in <module>raise ZeroDivisionError("重新抛出的ZeroDivisionError")
ZeroDivisionError: 重新抛出的ZeroDivisionError
"""
finally中执行return会导致异常丢失
如果finally语句的相关代码中包含了跳转语句,比如break,continue或return,那么这些跳转语句的执行,将导致未被except处理的 Python 异常不再被重新抛出,即便这些异常是通过raise语句主动抛出的
3.8 版本之前,在 Python 的finally语句的相关代码中,不能使用continue语句
finally中出现return语句,如果try中抛出的异常没有被捕获到,按理说当finally执行完毕后,应该被再次抛出,但finally里执行了return,导致异常被丢失,所以实际应用中,不推荐在finally中使用return返回
def test():try:5/0print("函数中的后续代码被执行")except IndexError as e: # 无法捕获除0异常print("IndexError")except KeyError as e: # 无法捕获除0异常print("KeyError")except ValueError as e: # 无法捕获除0异常print("ValueError")finally:print('输出:finally')return 1num = test()
print(num)print("后续代码被执行")# 输出结果:
"""
输出:finally
1
后续代码被执行
"""
raise 语句
raise 语句以及异常对象
使用 Python 提供的raise语句,开发人员可以主动抛出(引发)一个 Python 异常
raise 语句基本的语法形式为 raise <exception>
- exception
- 被抛出的 Python 异常对象,或 Python 异常类型如果仅给出异常类型,那么将根据该类型隐式创建其对应的实例,比如,raise ZeroDivisionError的效果等同于raise ZeroDivisionError()
raise ZeroDivisionError# 抛出异常:
"""
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 1, in <module>raise ZeroDivisionError
ZeroDivisionError
"""# 前后对比,发现效果一致
raise ZeroDivisionError()# 抛出异常:
"""
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 1, in <module>raise ZeroDivisionError()
ZeroDivisionError
"""
创建异常对象时可以指定其魔法方法__str__的返回值
# 判断ZeroDivisionError()返回的东西是否为ZeroDivisionError的实例对象
ins = ZeroDivisionError()
flag = isinstance(ins, ZeroDivisionError)
print(flag)# 输出结果:Trueins = ZeroDivisionError()
dir(ins) # 可以获知,该实例对象具有魔法方法__str__# 输出结果:
"""
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__','__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'with_traceback']
"""# 由于调用print函数实际是执行实例对象的魔法方法__str__,打印结果为该方法返回值
# 所以可以推断出实例化异常对象时,传入的"This is a ZeroDivisionError"
# 实际就是魔法方法__str__的返回值
ins = ZeroDivisionError("This is a ZeroDivisionError")
print(ins) # 输出结果:This is a ZeroDivisionErrorins = ZeroDivisionError("This is a ZeroDivisionError")
describe_string = ins.__str__() # 手动调用魔法方法__str__,打印该方法的返回值
print(describe_string)# 输出结果:This is a ZeroDivisionErrordata = 10
ins = ZeroDivisionError("This is a ZeroDivisionError, carry a data: %s" % data )
print(ins) # 输出结果:This is a ZeroDivisionError, carry a data: 10
在except语句中,可以使用 raise 语句,将raise语句的exception部分留空,这会将当前被处理的 Python 异常重新抛出(引发)
但是以上做法的效果并不等同于调用exception函数的语句raise sys.exception(),或类似于raise err的语句(假设err为as关键字绑定的标识符),他们会展示不同的回溯(Traceback)信息
# calculate.py文件的内容
def divide(a, b): # 进行除法运算的函数return a / b# main.py文件的内容
from calculate import dividedivide(5, 0)# 抛出异常:
"""
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 3, in <module>divide(5, 0)File "C:\编程\Python代码\test\calculate.py", line 2, in dividereturn a / b
ZeroDivisionError: division by zero
"""# calculate.py文件的内容
def divide(a, b): # 进行除法运算的函数return a / b# main.py文件的内容
from calculate import dividetry:divide(5, 0)except ZeroDivisionError:print("ZeroDivisionError异常被捕获")raise # 使用raise重新抛出异常# 抛出异常:
"""
ZeroDivisionError异常被捕获
Traceback (most recent call last):File "C:\编程\Python代码\test\test.py", line 4, in <module>divide(5, 0)File "C:\编程\Python代码\test\calculate.py", line 2, in dividereturn a / b
ZeroDivisionError: division by zero
"""# calculate.py文件的内容
def divide(a, b): # 进行除法运算的函数return a / b# main.py文件的内容
from calculate import dividetry:divide(5, 0)except ZeroDivisionError as e:print("ZeroDivisionError异常被捕获")raise e # 抛出异常:
"""
ZeroDivisionError异常被捕获
Traceback (most recent call last):File "C:\编程\Python代码\test\test.py", line 8, in <module>raise eFile "C:\编程\Python代码\test\test.py", line 4, in <module>divide(5, 0)File "C:\编程\Python代码\test\calculate.py", line 2, in dividereturn a / b
ZeroDivisionError: division by zero
"""
抛出异常时,自动创建的异常对象的魔法方法__str__的返回值即为 traceback 最后一行针对该异常的描述信息
5 / 0# 抛出异常:
"""
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 1, in <module>5 / 0
ZeroDivisionError: division by zero
"""try:5 / 0except ZeroDivisionError as e:# 判断 e 是否为ZeroDivisionError的实例对象flag = isinstance(e, ZeroDivisionError)print(flag)# 手动调用魔法方法__str__,打印该方法的返回值,进行对比describe_string = e.__str__() print(e)print(describe_string)# 输出结果:
"""
True
division by zero
division by zero
"""try:5 / 0except ZeroDivisionError as e:print("自动抛出的异常被捕获")raise e# 输出结果:
"""
自动抛出的异常被捕获
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 6, in <module>raise eFile "C:\编程\Python代码\test\main.py", line 2, in <module>5 / 0
ZeroDivisionError: division by zero
"""
自行创建一个异常对象,通过raise抛出,同时携带自定义的描述信息
try:5 / 0except ZeroDivisionError as e:print("自动抛出的异常被捕获")raise ZeroDivisionError("<division by zero>")# 输出结果:
"""
自动抛出的异常被捕获
Traceback (most recent call last):File "C:\编程\Python代码\test\main.py", line 6, in <module>raise ZeroDivisionError("<division by zero>")
ZeroDivisionError: <division by zero>
"""
raise…from 语句
如果一个 Python 异常已经被某个except语句处理,而该except语句的相关代码引发了新的异常,如果新的 Python 异常是通过raise…from语句引发,那么可以为新的 Python 异常指定一个表示原因的异常,用于说明新的 Python 异常是由该异常导致的
raise…from语句可以在其他位置使用,如果位于except语句的相关代码中,那么表示原因的异常一般被指定为已被except处理的 Python 异常,此时回溯信息将优先展示表示原因的 Python 异常的信息
raise…from 语句基本的语法形式为 raise <newexception> from <causeexception>
-
newexception
- 被抛出的 Python 异常对象,或 Python 异常类型。如果仅给出异常类型,那么将根据该类型隐式创建其对应的实例,比如,raise RuntimeError from ValueError()的效果等同于raise RuntimeError() from ValueError()
-
causeexception
- 表示原因的 Python 异常对象,或 Python 异常类型。如果仅给出异常类型,那么将根据该类型隐式创建其对应的实例,比如,raise RuntimeError() from ValueError的效果等同于raise RuntimeError() from ValueError()
Python 异常的基类 BaseException
在 Python 中,所有异常(表示异常的类)都需要继承自BaseException或Exception,这包括 Python 的内置异常,以及由开发人员定义的异常(当然,只有少数 Python 异常直接继承自类BaseException,大部分 Python 异常均继承自类Exception或类Exception的派生类)
- Python 异常基类 BaseException 和 Exception 之间的区别
- Exception是BaseException类的派生类,他表示不是来自于系统的非正常情况,比如,表示除数为0的 Python 异常ZeroDivisionError
- 一般情况下,开发人员仅需要捕获从Exception类派生的各种 Python 异常,如果将捕获的范围扩大到BaseException,那么可能会导致一些意想不到的问题
- 如果except后没有指定异常类型,则默认捕获所有的异常,即此时捕获异常范围为BaseException, 这样的没有指定异常类型的 except 语句要求必须是最后一个 except 语句,否则程序报错,原因很简单,如果它位于其他except语句之前,那么一些except语句将失去被执行的可能
如果将捕获异常的范围扩大到BaseException,可能会导致sys.exit()无法退出 Python 解释器
import systry:sys.exit() # 尝试退出程序
except BaseException as e:print(f'捕获到了异常 {type(e)}')print('sys.exit() 已经执行,但是程序没有成功退出')# 输出结果:
"""
捕获到了异常 <class 'SystemExit'>
sys.exit() 已经执行,但是程序没有成功退出
"""
相关文章:

Python——异常处理机制
Python 异常处理机制 Python异常与异常处理机制针对 Traceback 的解读try-except-else-finallyexcept语句except语句的机制在 except 语句中引用当前被处理的 Python 异常 finally语句finally语句执行后才能抛出未被处理的异常finally中执行return会导致异常丢失 raise 语句rai…...

社群团购中的用户黏性价值:以开源小程序多商户AI智能名片商城源码为例
摘要:本文探讨社群团购中的用户黏性价值,分析其与传统团购网站的区别,并阐述开源小程序多商户AI智能名片商城源码在增强社群团购用户黏性方面可能发挥的作用。 一、引言 在当今的商业环境中,社群团购逐渐成为一种重要的营销模式。…...

基于php的民宿预订管理系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...
java 从基础到入门 到架构师所需要学习的路线
java是一种广泛使用的编程语言,可以应用于多种平台和应用程序。下面是一个从基础到入门,再到架构师所要掌握的Java学习路线的详细列举: 学习Java基础知识: 理解面向对象编程的概念,如类、对象、继承、多态等。 学习Ja…...

【吊打面试官系列-MySQL面试题】什么叫视图?游标是什么?
大家好,我是锋哥。今天分享关于【什么叫视图?游标是什么?】面试题,希望对大家有帮助; 什么叫视图?游标是什么? 视图是一种虚拟的表,具有和物理表相同的功能。可以对视图进行增&#…...
项目管理-信息技术发展
1、计算机软硬件 2、计算机网络 1)定义 2)分类:PAN LAN MAN WAN 公用网 专用网 3)网络协议 语法 语义 时许 4)网络标准协议 7层 5)IEEE 802 规范 6)TCP/IP 协议 7) SDN 软件定义网…...

异常处理【C++提升】(基本思想,重要概念,异常处理的函数机制、异常机制,栈解旋......你想要的全都有)
更多精彩内容..... 🎉❤️播主の主页✨😘 Stark、-CSDN博客 本文所在专栏: C系列语法知识_Stark、的博客-CSDN博客 座右铭:梦想是一盏明灯,照亮我们前行的路,无论风雨多大,我们都要坚持不懈。 异…...

基于springboot vue 电影推荐系统
博主介绍:专注于Java(springboot ssm 等开发框架) vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…...

八、特殊类型异常机制
特殊类型&异常机制 数据类型枚举类型匿名类、单例类和伴生对象匿名类单例类伴生对象 委托模式密封类型异常机制异常的使用异常的处理 数据类型 对于那些只需要保存数据的类型,我们常常需要为其重写toString、equals等函数,针对于这种情况下…...
虾皮Shopee Android面试题及参考答案
HTTP 状态码有哪些? HTTP 状态码是用以表示网页服务器超文本传输协议响应状态的 3 位数字代码。主要分为五大类: 1xx 信息性状态码:表示服务器正在处理请求,这些状态码是临时的响应,主要用于告诉客户端请求已经被接收,正在处理中。例如,100 Continue 表示客户端应当继续…...
Docker Compose 部署大模型GPU集群:高效分配与管理算力资源
Docker Compose 部署大模型GPU集群:高效分配与管理算力资源 文章目录 Docker Compose 部署大模型GPU集群:高效分配与管理算力资源一 Dockerfile 编写二 Dockerfile 示例三 分配GPU资源1)GPU分配:指定count2)GPU分配&am…...

直立行走机器人技术概述
直立行走机器人技术作为现代机器人领域的重要分支,结合了机械工程、计算机科学、人工智能、传感技术和动态控制等领域的最新研究成果。随着技术的不断发展,直立行走机器人在救灾、医疗、家庭辅助等领域开始发挥重要作用。本文旨在对直立行走机器人的相关…...
【Linux】wsl虚拟机时间和实际时间不符合
本文首发于 ❄️慕雪的寒舍 偶然遇到了这个问题,触发原因是电脑在开启wsl的情况下进入了 休眠 模式,且在无网络情况下几天不使用。 然后开启wsl,发现git log显示最新commit的提交时间是明天,给我吓一跳,然后才发现原来…...

初识算法 · 滑动窗口(1)
目录 前言: 长度最小的子数组 题目解析 算法原理 算法编写 无重复长度的最小字符串 题目解析 算法原理 算法编写 前言: 本文开始,介绍的是滑动窗口算法类型的题目,滑动窗口本质上其实也是双指针,但是呢&#…...

nginx和gateway的关系和区别
在技术选型时,选择 Nginx 和 Spring Cloud Gateway(或简称为 Gateway)主要取决于具体应用场景和技术需求。下面是两者的一些关键差异和适用场景。 一、Nginx 概念 Nginx 是一个高性能的 Web 服务器和反向代理服务器,常被用作静…...

【算法笔记】滑动窗口算法原理深度剖析
【算法笔记】滑动窗口算法原理深度剖析 🔥个人主页:大白的编程日记 🔥专栏:算法笔记 文章目录 【算法笔记】滑动窗口算法原理深度剖析前言一.长度最小的子数组1.1题目1.2思路分析1.3算法流程1.4正确性证明1.5代码实现 二.无重复…...

4S店4S店客户管理系统小程序(lw+演示+源码+运行)
社会的发展和科学技术的进步,互联网技术越来越受欢迎。手机也逐渐受到广大人民群众的喜爱,也逐渐进入了每个用户的使用。手机具有便利性,速度快,效率高,成本低等优点。 因此,构建符合自己要求的操作系统是非…...
rabbitMq------连接管理模块
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言管理的字段连接内存管理对象 前言 我们的网络通信框架使用的muduo库,而在mudu库中是已经有了连接的概念,但是我们呢还有一个信道的概念…...
【部署项目】禹神:前端项目部署上线笔记
1.项目打包 ● 我们开发用的脚手架其实就是一个微型服务器,用于:支撑开发环境、运行代理服务器等。 ● 打包完的文件中不存在:.vue、.jsx、.less 等文件,而是:html、css、js等。 ● 打包后的文件,不再借助…...
力扣10.1
983. 最低票价 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 火车票有 三种不同的销售方式 : 一张 为期一天 的通行证售…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
Go 语言并发编程基础:无缓冲与有缓冲通道
在上一章节中,我们了解了 Channel 的基本用法。本章将重点分析 Go 中通道的两种类型 —— 无缓冲通道与有缓冲通道,它们在并发编程中各具特点和应用场景。 一、通道的基本分类 类型定义形式特点无缓冲通道make(chan T)发送和接收都必须准备好࿰…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...
十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建
【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...