错误和异常
- 错误:没法通过其他的代码进行处理的问题
语法错误
逻辑错误
- 异常:程序在执行的过程中出现的未知错误,语法和逻辑均正确,可以通过其余的代码进行修复。
异常:除0异常、名称异常、类型异常、索引异常、键异常、值异常、属性异常、迭代器异常(StopIteration)、
解决异常:增加容错处理
方案一:try except
try:
print(name)
except NameError as Ne:
print("name未定义", Ne)
except ZeroDivisionError:#捕获到一个错误就跳到else
print("除零错误")
else:
print("okk")
finally:
print("hello world")
'''name未定义 name 'name' is not defined
hello world'''
# # try:
# 可能会出现异常的代码
# # except + 要捕捉的异常的类型:
# 对捕捉到的异常的处理
# # else: 可省略
# 没出现异常的处理
# # finally: 可省略
# 无论是否出现异常都会处理
如果异常名称不确定,可以写Exception。
try:
print(name)
except (NameError, ZeroDivisionError) as Ne:#合并多个异常
print("name未定义", Ne)
except Exception as a:
print("不知名错误")
else:
print("okk")
finally:
print("hello world")
方案二:
适用于执行某一段代码A之前,进行预处理,执行代码A之后,进行清除操作。
格式:
with context_expression [as target(s)]
with-body
1、context_expression要返回一个上下文管理器对象(即实现了上下文协议的对象,必须要实现__enter__()、exit()俩个方法)
2、调用enter方法,如果有 [as target(s)],则将enter方法的返回值赋值给target
3、执行语句体
4、执行上下文管理器的exit方法
with open("1.png", "rb") as f:
f.readlines()
import traceback
class Text:
def __enter__(self):
print("Hello, entered!")
def __exit__(self, exc_type, exc_val, exc_tb):
'''
:param exc_type: 异常的类型
:param exc_val: 异常的值
:param exc_tb: 异常的追踪信息
:return:返回True则不会向外界抛出异常 哪个文件哪一行出现了错误信息
'''
print(traceback.extract_tb(exc_tb))
print(self, exc_type, exc_val, exc_tb, "goodbey!")
with Text() as target:
1/0
'''
Traceback (most recent call last):
File "D:\file\python学习\test.py", line 17, in <module>
1/0
ZeroDivisionError: division by zero
Hello, entered!
[<FrameSummary file D:\file\python学习\test.py, line 17 in <module>>]
<__main__.Text object at 0x000001A9040F4160> <class 'ZeroDivisionError'> division by zero <traceback object at 0x000001A90438CF00> goodbey!
'''
生成器和上下文管理器
import contextlib
@contextlib.contextmanager
def test():
'''
:return: yiled的上面语句作为enter 下面作为exit
yield后面的值就可以用于target
'''
print("1")
yield "xxx"
print("2")
with test() as x:
print(3, x)
'''
1
3 xxx
2
'''
@contextlib.contextmanager
def ze():
try:
yield
except ZeroDivisionError as e:
print("error", e)
with ze():
1/0 #error division by zero
手动抛出异常
def set_age(age):
if age <= 0 or age >= 200:
raise ValueError("错误")
else:
print("设置年龄为", age)
try :
set_age(-18)
except ValueError as e:
print("error", e)
#error 错误
raise 语句抛出的异常对象必须继承自BaseException;自定义的异常类要继承自Exception.
class LessZero(Exception):
def __init__(self, msg, error_code):
self.msg = msg
self.error_code = error_code
def __str__(self):
return self.msg + str(self.error_code)
def set_age(age):
if age <= 0 or age >= 200:
raise LessZero("错误", 404)
else:
print("设置年龄为", age)
try :
set_age(-18)
except LessZero as e:
print(e) #错误404