# Python - 异常处理
# 异常和错误的概念
# 错误:
# 语法错误:比如写成: dle xxx()
# 逻辑错误: if age < 18 : print("已经成年")
# 异常:多出现在程序的执行过程中,出现的未知错误;语法和逻辑都正确
# 异常可以通过代码来修复
# 常见的系统异常
# 除0异常;
# 异常名称:ZeroDivisionError
# 名字异常:用了一个没有定义的名称;
# 如:print(name);
# 异常名称:NameError
# 类型异常:"a" + 10
# 异常名称:TypeError
# 索引异常:l = [1,2] l[2]
# 异常名称:IndexError
# 键值异常:key = {"name":"abc", "age" : 18} key = {"name":"abc", "age" : 18}
# 异常名称:KeyError
# 值异常:int("abc")
# 异常名称:ValueError
# 属性异常:name = "abc" print(name.xxx)
# 异常名称:AttributeError
# 迭代器异常:
# it = iter([1, 2])
# next(it)
# next(it)
# next(it)
# 异常名称:StopIteration
# 情况一
try:
1 / 0
print(name)
except (ZeroDivisionError, NameError) as e:
print(e)
else:
print("else")
finally:
print("finally")
# 情况二, 下面为优,Exception
try:
# 1 / 0
print(name)
except Exception as e:
print(e)
else:
print("else")
finally:
print("finally")
# ---------------- 上下文管理器 ---------------------
# 可以自定义上下文管理器:在执行一个主题时先定义 __enter__, __exit__
class Test():
def __enter__(self):
print("enter")
return 1;
def __exit__(self, exc_type, exc_val, exc_tb):
print(self, exc_type, exc_val, exc_tb)
#得到异常的错误信息,可以把这些形象写入到日子文件里
import traceback
traceback.extract_tb(exc_tb)
print("exit")
return True # 返回True,异常错误信息不会往外传,否则会往外传
print(Test().__enter__()) # 1
# with 语句
# as x 其中x代表前面表达式中__enter__的返回值
with Test() as t:
print("body", t)
1 / 0
# 输出如下信息:
# enter
# body None
# <__main__.Test object at 0x01CBB9D0> None None None
# 1 / 0 显示为下面的结果
#<__main__.Test object at 0x0343B9D0> <class 'ZeroDivisionError'> division by zero <traceback object at 0x03525F08>
# exit
# yield 前面的成为 __enter__
# yield 后面的"return" 成为 __enter__的返回值
# yield 后面下面的语句成为__exit__的内容
def test():
print(1)
yield "return"
print(2)
# 通过contextlib 来构造上下文管理器
import contextlib
@contextlib.contextmanager
def ze():
try:
yield
except Exception as e:
print(e)
# division by zero
with ze():
10 / 0
# 快速把对象里面有close的方法变成上下文管理器,前提是对象里面必须要有close
class Test():
def start(self):
print("start")
def close(self):
print("close")
import contextlib
with contextlib.closing(Test()) as obj:
obj.start()
# start
# close
# Python 3.0 以后的嵌套方法
# 第一种写法
with open("1.png", "rb") as from_file:
with open("3.png", "wb") as to_file:
content = from_file.read()
to_file.write( content )
# 第二种写法
with open("1.png", "rb") as from_file, open("4.png", "wb") as to_file:
content = from_file.read()
to_file.write(content)
# -------------------- 手动抛出异常 --------------------
def set_age(age):
if 0 <= age < 200 :
print("你的年龄:", age)
else:
# print("值错误")
# 下面的是直接抛出异常错误给外面
raise ValueError("值错误")
set_age(18) # 你的年龄: 18
try:
set_age(-18)
except ValueError as e:
print(e) # 值错误
# ------------------- 自定义异常 -------------------------
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 0 <= age < 200 :
print("你的年龄:", age)
else:
# print("值错误")
# 下面的是直接抛出异常错误给外面
raise LessZero("值错误", 404)
try:
set_age(-18)
except LessZero as e:
print(e) # 值错误404