双下方法补充以及异常处理

双下方法补充以及异常处理

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代码解决过程繁琐复杂.异常处理要慎用,精用.
posted @ 2019-08-12 20:57  Bugbiss  阅读(104)  评论(0编辑  收藏  举报