day18 约束 异常
1. 类的约束 方案一:抛出异常,子类必须重写父类方法,否则会报错 class Base: def login(self): #强制xxx做XXX事 raise NotImplementedError("子类没有实现该方法") #报错 异常 class Normal( Base): def login(self): print("普通人登录") class Admin( Base): def login(self): print("管理员登录") class Member( Base): def denglu(self): #方法的覆盖和重写 print("会员登录") def login(obj): obj.login() n=Normal() login(n) a=Admin() login(a) m=Member() #报错 login(m) 在执行到login(m)的时候程序会报错. 原因是, 此时访问的login()是父类中的方法. 但是父 类中的方法会抛出一个异常. 所以报错. 这样程序员就不得不写login方法了. 从而对子类进行 了相应的约束,这是一套方案.
抽象的概念:如果一个类中包含抽象方法. 那么这个类一定是一个抽象类. 抽象类是不能有实例的,但是抽象类中是可以有普通方法的 方案二:使用元类来描述父类. 在元类中给出一个抽象方法. 这样子类就不得不给出抽象 方法的具体实现. 也可以起到约束的效果. from abc import ABCMeta,abstractmethod class Animal(metaclass=ABCMeta): #类中包含抽象方法,此类就是抽象类,zhu:抽象类可以有普通方法 @abstractmethod def chi(self): #抽象的概念 pass class Cat(Animal): #子类必须实现父类的方法,否则子类也是抽象类 def chi(self): #子类对抽象概念的实现,重写 print("用犬齿吃") c=Cat() c.chi() a=Animal() #报错,报错的原因自己给出 a.chi()
语法: from abc import ABCMeta, abstractmethod class Base(metaclass = ABCMeta): 抽象类 @abstractmethod def 方法(self):pass class Foo(Base): 子类必须重写父类中的抽象方法 def 方法(self): pass 一个类包含类抽象方法. 这个类一定是抽象类 抽象类中可以有正常的方法 抽象类中如果有抽象方法. 这个类将不能创建对象 接口: 类中都是抽象方法
总结:其实就是父类对子类的约束,子类必须实现XX方法,有两个方案
方案一:使用抽象类和抽象方法,使用频率较低
方案二:使用人为的跑出异常,并尽量使用NotImplementedError,这样比较专业,明确
2. 异常处理 1. 异常:程序运行中的出现的错误 例: def chu(a, b) return a/b ret = chu(10,0) #报错了,除数不能为0 print(ret) 异常的处理: def chu(a,b) return a/b try: ret=chu(a,b) print(ret) except Exception as e: print("除数不能为0")
2 .语法: try: """操作""" except Exception as e: """异常的父类,可以捕捉所有的异常""" else: """保护不抛出异常的代码,当try中无异常的时候运行""" finallly: 最后总要执行我 程序先执行操作, 然后如果出错了会走except中的代码. 如果不出错, 执行else中 的代码. 不论处不出错. 最后都要执行finally中的语句. 一般我们用try...except就够了. 顶多 加上finally. finally一般用来作为收尾工作. 3.自定义异常 例.#继承了Exception就是一个有异常类 import traceack #引入traceback 为了获得堆栈信息 class GenderException(Exception): pass class Person: def __init__(self,name,gender): self.name=name self.gender=gender def bush(self): if self.gender!="男": raise GenderException("性别不对") #除了名字一以外都是父类中的Exception else: print("欢迎洗大唧唧") try: p1=Person("吴奇隆","男") p1.bush() p2=Person("小三","女") p2.bush() except GenderException as e: val=traceback.format_exc() #获取到堆栈信息 print(val) #测试的时候打印堆栈信息,给客户的时候就撤掉 print("没吊不要进来") except Exception as e: print("其他错误")
#附一个,老师的实例,比较鲜明 #一切皆文件 import abc #利用abc模块实现抽象类 class All_file(metaclass=abc.ABCMeta): all_type='file' @abc.abstractmethod #定义抽象方法,无需实现功能 def read(self): '子类必须定义读功能' pass @abc.abstractmethod #定义抽象方法,无需实现功能 def write(self): '子类必须定义写功能' pass # class Txt(All_file): # pass # # t1=Txt() #报错,子类没有定义抽象方法 class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法 def read(self): print('文本数据的读取方法') def write(self): print('文本数据的读取方法') class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法 def read(self): print('硬盘数据的读取方法') def write(self): print('硬盘数据的读取方法') class Process(All_file): #子类继承抽象类,但是必须定义read和write方法 def read(self): print('进程数据的读取方法') def write(self): print('进程数据的读取方法') wenbenwenjian=Txt() yingpanwenjian=Sata() jinchengwenjian=Process() #这样大家都是被归一化了,也就是一切皆文件的思想 wenbenwenjian.read() yingpanwenjian.write() jinchengwenjian.read() print(wenbenwenjian.all_type) print(yingpanwenjian.all_type) print(jinchengwenjian.all_type)