今日主要内容 1. 约束(1. 抛出异常, 2. 写抽象类)(难点, 重点) 1. 抛出异常; NotImplementedError 例 class Base: def login(self): # 强制子类做xxxx事 raise NotImplementedError("子类没有实现该方法") # 报错. 抛异常 # 1. 普通账号 --> 翔哥 class Normal(Base): def login(self): print("普通账号的登录") # 2. 吧务 - > 强哥 class Member(Base): def login(self): print("吧务的登录") # 3. 百度员工 -> 明哥 class Admin(Base): def denglu(self): # 方法的覆盖和重写 print("管理员的登录") # 项目经理 def wodetian(obj): obj.login() n = Normal() wodetian(n) m = Member() wodetian(m) a = Admin() wodetian(a) 2. 抽象类 from abc import ABCMeta, abstractmethod class Base(metaclass = ABCMeta): 抽象类 @abstractmethod def 方法(self):pass class Foo(Base): 子类必须重写父类中的抽象方法 def 方法(self): pass 一个类包含类抽象方法. 这个类一定是抽象类 抽象类中可以有正常的方法 抽象类中如果有抽象方法. 这个类将不能创建对象 接口: 类中都是抽象方法 例 from abc import ABCMeta, abstractmethod # 贴吧 # 项目经理(级别高一点儿) class Base(metaclass=ABCMeta): # 抽象类 # 抽象方法 @abstractmethod # staticmethod, classmethod def login(self): # 强制子类做xxxx事 pass def hehe(self): # 抽象类中可以有正常的方法 print("我会呵呵呵") # b = Base() # 报错的. 原因是Base是一个抽象类. 含有抽象方法. 不允许创建对象的 # 一个类如果全部都是抽象方法. 这个类可以被称为接口. 用来约束子类和规范子类 # 1. 普通账号 --> 翔哥 class Normal(Base): pass def login(self): # 重写了父类中的抽象方法 print("普通账号的登录") n = Normal() n.login() 2. 异常处理 try: except Error as e: except.... else: finally: 收尾 我们在调试的时候, 最好是能看到错误源⾃于哪⾥? 怎么办呢? 需要引入另⼀个模块traceback. 这个模块可以获取到我们每个⽅法的调⽤信息. 被成为堆栈信息. 这个信息对我们拍错是很有帮助的. import traceback try: # 尝试执行的代码 except Exception as e: # 除了错之后要做什么 traceback.format_exc() # 获取堆栈信息(错误信息) 例 # import traceback # # 计算a+b # def cul(a, b): # if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float): # return a + b # else: # # 在这里有两种方案. 1. 直接返回 , 2. 抛出异常 # # raise 抛出 Exception 错误和异常,所有错误的根 # raise Exception("我要的不是这个. 你应该我传递int或者float") # # # try: # print(cul(1, "胡辣汤")) # 加上异常的处理 # except Exception as e: # # 获取到错误信息. 我们需要访问堆栈信息 # print(traceback.format_exc()) # 获取堆栈信息 # print("出现了错误") 3. 日志处理 logging critical error(最多) wraning info debug 例 模板 # filename: ⽂件名 # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦ # 时间-名称-级别-模块: 错误信息 # datefmt: 时间的格式 # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件 logging.basicConfig(filename='x1.txt', format='%(asctime)s - %(name)s - %(levelname)s -% (module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=0) # 当前配置表示 10以上的分数会被写⼊⽂件 # CRITICAL = 50 # FATAL = CRITICAL # ERROR = 40 # WARNING = 30 # WARN = WARNING # INFO = 20 # DEBUG = 10 # NOTSET = 0 logging.critical("我是critical") # 50分. 最贵的 logging.error("我是error") # 40分 logging.warning("我是警告") # 警告 30 logging.info("我是基本信息") # 20 logging.debug("我是调试") # 10 logging.log(2, "我是⾃定义") # ⾃定义. 看着给分 class JackError(Exception): pass for i in range(10): try: if i % 3 == 0: raise FileNotFoundError("⽂件不在啊") elif i % 3 == 1: raise KeyError("键错了") elif i % 3 == 2: raise JackError("杰克Exception") except FileNotFoundError: val = traceback.format_exc() logging.error(val) except KeyError: val = traceback.format_exc() logging.error(val) except JackError: val = traceback.format_exc() logging.error(val) except Exception: val = traceback.format_exc() logging.error(val)