约束和异常处理:
内容梗概:
1. 类的约束
2. 异常处理
3. 自定义异常
4. 日志
1. 类的约束
定义:约束是对类的约束
常用方法:
1. 提取父类.然后在父类中定义好方法.在这个方法中什么都不用干.就抛⼀个异常就可以了.
这样所有的子类都必须重写这个方法.否则.访问的时候就会报错.
2. 使用元类来描述父类. 在元类中给出⼀个抽象方法. 这样子类就不得不给出抽象方法的具体实现. 也可以起到约束的效果.
法一:提取父类
class Base: def login(self): # 强制子类做xxxx事 raise Exception("没有实现login的方法") raise NotImplementedError("没有实现login的方法") #专业的写法 class admin(Base): def login(self): print("管理员的登录") class user(Base): def denglu(self): print("用户的登录") a = admin() a.login() u = user() u.login() #报错 u.denglu()
法二:抽象方法
from abc import ABCMeta,abstractmethod class Animal(metaclass = ABCMeta): @abstractmethod def chi(self): pass class cat(Animal): def shui(self): print("我要睡") def chi(self): print("我要吃") b = Animal() # 报错的. 原因是Base是一个抽象类. 含有抽象方法. 不允许创建对象的 c = cat() c.chi()
总结:
当我们需要对子类进行约束:
1.抛出异常
NotImplementedError() 没有实现 -> 约定俗成.多观察
2.写抽象类
from abc import ABCMeta, abstractmethod class Base(metaclass=ABCMeta): @abstractmethod def 方法(self): pass
如果一个类中包含了抽象方法.那么这个类一定是一个抽象类,一个抽象类中可以包含正常的方法
接口: 接口中所有的方法都是抽象方法
子类必须重写父类中的抽象方法.否则子类也是一个抽象类
2. 异常处理
处理流程:
try:
xxxx
except 错误名称 as 别名:
出现错误的时候. 要干什么...
except 错误名称 as 别名:
出现错误的是偶. 要干什么
....
except Exception as e: # 所有错误的根
出现的所有的错误. 我都可以这样处理
else: # 很少用到
不出错的时候执行这里的代码
finally:
结束. 收尾工作
解读: 程序先执行行操作,然后如果出错了了会走except中的代码.如果不出错,执行else中的代码.
不论处不出错 最后都要执行finally中的语句.一般我们用try...except就够用了了.顶多加上finally(一般用来作为收尾)
抛异常:
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.自定义异常:
定义:
只要你的类继承了了Exception类.那你的类就是⼀一个异常类. 就这么简单.
实例:
自定义异常
class GenderException(Exception): pass class Person: def __init__(self, name, gender): self.name = name self.gender = gender # 洗澡 -> 男的进男浴室 def goto_nan_yushi(self): if self.gender != "男": raise GenderException("性别不对") # 除了名字以外都是父类中的Exception else: print("欢迎光临.") try: p2 = Person("wusir", "女") p2.goto_nan_yushi() p1 = Person("alex", "男") p1.goto_nan_yushi() except GenderException as e: print("你去男澡堂子干嘛?") except Exception as e: print("其他错误")
5.日志
格式:
import logging # filename: ⽂件名 # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦ # 时间-名称-级别-模块: 错误信息 # datefmt: 时间的格式 # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件 logging.basicConfig(filename='x1.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=30) # 当前配置表示 0以上的分数会被写⼊⽂件 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("我是warning") logging.info("我是info") logging.debug("我是debug") logging.log(1, "我什么都不是")
实例:
import traceback try: print(1/0) except Exception: logging.error(traceback.format_exc()) # 用法 print("出错了")
当一个系统有两个子文件时,可采用这种方式分开记录,方便查找
import logging 创建⼀个操作⽇志的对象logger(依赖FileHandler) file_handler = logging.FileHandler('zuo.log', 'a', encoding='utf-8') # open() file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) logger1 = logging.Logger('A系统', level=20) logger1.addHandler(file_handler) # 把文件助手和日志对象绑定 logger1.error('我是A系统出错了') # 记录日志 再创建⼀个操作⽇志的对象logger(依赖FileHandler) file_handler2 = logging.FileHandler('you.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('B系统', level=20) logger2.addHandler(file_handler2) logger2.error('我是B系统出错了') import traceback try: print(1/0) except Exception: logger2.error(traceback.format_exc()) #常见搭配用法 print("出错了. 请联系管理员") print("程序继续执行")