双下方法补充以及异常处理
1.双下方法补充
1.__item__系列
__getitem__,__setitem__,__delitem__ 对对象做类似于字典的(增删改查)触发__item__系列
__delattr__ del obj.属性时.就会触发此方法
class Foo:
def __init__(self,name):
self.name = name
def __getitem__(self,item):
print(item)
return self.__dict__[item]
def __setitem__(self,key,value):
self.__dict__[key] = value
print(key)
print(value)
def __delitem__(self,key):
print('del obj[key]时,我执行')
def __delattr__(self,item):
super().__delattr__(item) #重写了__delattr__方法,所以必须调用父类的__delattr__方法,obj.item属性才能被真正删除
print(f"对象的{item}属性已经删除")
obj = Foo("奇奇")
print(obj['name']) # name 奇奇
obj[1] = 2 # 1 2
del obj[1] # del obj[key]时,我执行
def obj.name # 对象的name属性已经删除
2.上下文管理器相关
__enter__,__exit__,(with操作)
# 如果想要对一个类的对象进行with as 的操作,则不行。
class A:
def __init__(self, text):
self.text = text
with A('大爷') as f1:
print(f1.text) #会报错
#实例化对象的第二种方式: 必须基于 __enter__ 以及 __exit__这个两个方法.
class A:
def __init__(self, text):
self.text = text
def __enter__(self): # 开启上下文管理器对象时触发此方法
self.text = self.text + '您来啦'
return self # 将实例化的对象返回f1
def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法
self.text = self.text + '这就走啦'
with A('大爷') as f1:
print(f1.text)
print(f1.text)
#大爷您来啦
#大爷您来啦,这就走啦
#执行流程:
class A:
def __init__(self, text):
self.text = text
def __enter__(self): # 开启上下文管理器对象时触发此方法
self.text = self.text + '您来啦' # 第一步
print(11111)
return self # 必须!!!将实例化的对象返回f1
def __exit__(self, exc_type, exc_val, exc_tb): # 执行完上下文管理器对象f1时触发此方法
print(333) # 第三步
self.text = self.text + ',这就走啦'
with A('大爷') as f1:
print(2222)
print(f1.text) # 第二步
print(f1.text) # 第四步
#11111
#2222
#大爷您来啦
#333
#大爷您来啦,这就走啦
3.__iter__
class A:
def __init__(self,name):
self.name = name
def __iter__(self):
for i in range(3):
yield i
obj = A("奇奇") #此时的obj为一个可迭代对象
for i in obj:
print(i)
# 0
# 1
# 2
print(obj.name)
# 奇奇
o = iter(obj) # 迭代器
print(next(o)) # 0
print(next(o)) # 1
print(next(o)) # 2
2.异常处理
什么是异常?
异常就是程序运行时发生错误的信号,程序发生异常错误之后,程序就中断了
程序中难免出现错误,而错误分成两种:
1.语法错误(过不了python解释器的语法检测,必须在程序执行前就改正)
例:
if 2 > 1
def test:
pass
dic = {'name';"alex"}
tu = (2,3,1'6)
2.逻辑错误
num = int(input("请输入数字:"))
dic = {'name':'alex',"age":12}
dic['sex']
try举例:
try:
num = int(input(">>>"))#出现ValueError错误后,执行except后内容
print(111) #出现错误后不会执行
except ValueError:
print(222)
什么是异常处理?
当代码出现异常时,通过某种方式不让程序中断,让其执行另外一个处理分支,使程序不会崩溃.
为什么要有异常处理?
1.为用户提供良好的体验
2.增强代码的健壮性和容错性
异常处理的两种方式:
1.使用if判断式(只能处理简单的异常,如果异常需要考虑的方面比较多,则不适合)
2.利用try的方式进行异常处理
基本语法:
try:
被检测的代码块
except 异常类型:
try中一旦检测到异常,就执行这个位置的逻辑
异常处理结构:
结构1:单分支
try:
num = int(input(">>>"))
except ValueError:
print("输入的有非数字元素")
结构2:多分支
try:
num = int(input(">>>"))
dic = {"name":"奇奇"}
print(dic['age'])
lst = [1,2,3]
print(lst[10])
except ValueError:
print("输入的有非数字元素")
except KeyError:
print("没有此键")
except IndexError:
print("索引超出范围")
结构3:万能异常:处理所有python识别的异常
try:
num = int(input(">>>"))
dic = {"name":"奇奇"}
print(dic['age'])
lst = [1,2,3]
print(lst[10])
except Exception as e:
print(e)
#什么时候用万能异常?什么时候用多分支?
#如果对错误信息不关心,只是想要排除错误让程序继续运行,用万能异常
#对错误信息进行明确的分支,让程序多元发开发,用多分支
结构4:多分支+万能异常
try:
num = int(input(">>>"))
dic = {"name":"奇奇"}
print(dic['age'])
lst = [1,2,3]
print(lst[10])
except ValueError:
print("输入的有非数字元素")
except KeyError:
print("没有此键")
except Exception:
print("程序出现意外错误")
结构5: try else finally
try:
num = int(input(">>>"))
dic = {"name":"奇奇"}
print(dic['age'])
except ValueError:
print("输入的有非数字元素")
except KeyError:
print("没有此键")
else:
print("如果没有出现异常则执行这里")
finally:
print("无论异常与否,都会执行该模块,通常是进行清理工作")
# except必须依赖于try,else必须依赖于except和try
# finally只是依赖于finally
在异常出现之前,执行finally语句,finally用在关闭数据库连接,文件句柄关闭,数据保存等
# 在return结束函数之前,执行finally代码.
def func():
try:
print(111)
return 666
finally:
print(222)
print(func()) # 111 222 666
结构6:主动触发异常
try:
raise TypeError('类型错误')
except Exception as e:
print(e)
结构7:断言(assert):展现出一种强硬的态度
assert 条件
num = 1
n = input("请输入:")
assert num == n #判断条件成立后才执行下面的,否则报错
print(111)
结构8:自定义异常
python中提供了很多错误类型,但是不包括全部的错误
class Eva(BaseException): #BaseException为所有错误类型的父类
def __init__(self,msg):
self.msg=msg #EvaException为自己定义的错误类型
def __str__(self):
return self.msg
try:
raise Eva('类型错误')
except Eva as e:
print(e)
使用try...except的方式比较if的好处
try..except这种异常处理机制就是取代if那种方式,让你的程序在不牺牲可读性的前提下增强健壮性和容错性
异常处理中为每一个异常定制了异常类型(python中统一了类与类型,类型即类),对于同一种异常,一个except就可以捕捉到,可以同时处理多段代码的异常(无需‘写多个if判断式’)减少了代码,增强了可读性
使用try..except的方式
1:把错误处理和真正的工作分开来
2:代码更易组织,更清晰,复杂的工作任务更容易实现;
3:毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了.
异常处理: 实在用if代码解决不了;if代码解决过程繁琐复杂.异常处理要慎用,精用.