5.约束与异常处理
一.类的约束
约束是对类的约束
class Base: #对子类进行约束,必须重写该方法 #以后上班了,拿到公司代码之后,发现NotImplementedError继承它 直接重新写 def login(self): raise NotImplementedError("你要重新写login方法") class Member(Base): def login(self): print("我是普通人登录") class Bawu(Base): def login(self): print("吧务登录") class Houtai(Base): def login(self): print("后台登录") #整合这个功能 def deng(obj): obj.login() m = Member() bw = Bawu() ht = Houtai() deng(m) deng(bw) deng(ht)
python中设置约束的两种方法
1.提取父类,然后在父类中定义好方法,在这个方法中什么都不干直接抛一个异常就可以了,这样所有的子类都必须重写写这个方法,否则访问的时候会报错
2.使用元类来描述父类,在元类中给出一个抽象方法,这样子类不得不给出抽象方法的具体实现,也可以起到约束的效果
在python中写一个抽象类比较麻烦,就需要引入abc模块中的ABCMetea和abstractmethod这两个类容
#导入模块 from abc import ABCMeta ,abstractmethod #此时抽象类不能创建对象 class Animal(metaclass=ABCMeta): #抽象类 @abstractmethod #抽象方法 def chi(self):pass #抽象类中可以有正常的方法 def dong(self): print("动物会动") class Cat(Animal): def chi(self): #重写父类中的抽象方法 print("猫喜欢吃鱼") a = Cat() a.chi() a.dong()
总结:约束就是父类对子类进行约束,子类必须写方法
在python中约束的方法和方法有两种:
1.使用抽象类和抽象方法,由于该方案来源于java和c#,所以使用频率低
2.使用人为抛出异常的方案,尽量抛出的是NotImpementError,这样比较专业,而且错误比较明确
二.异常处理
# print(1/0) # print("哈哈")
抛出异常
Traceback (most recent call last): File "D:/s18/day20约束与异常/异常处理.py", line 3, in <module> print(1/0) ZeroDivisionError: division by zero
怎么解决呢
try: print(1/0) except Exception: print("出错了,出了ZeroDivisionError错误") print("哈哈")
多个异常的处理方法
try: print(1/0) f = open("哈哈哈哈",mode='r') d = {[]:123} except ZeroDivisionError: print("除以0是错的") except FileNotFoundError: print("文件不存在的错误") except Exception: print("其他错误") else: pass finally: print("哈哈哈哈哈")
finally:程序报错依然执行以下代码
Exception:万能异常,可以捕获任意异常
自定义异常
class CulException(Exception): pass def cul(a,b): if (type(a)==int or type(a)==float) and (type(b)==int or type(b) == float): return a+b else: raise CulException("我也没办法处理") print(cul("不放",2))
打印
Traceback (most recent call last): File "D:/s18/day20约束与异常/异常处理.py", line 36, in <module> print(cul("不放",2)) File "D:/s18/day20约束与异常/异常处理.py", line 34, in cul raise CulException("我也没办法处理") __main__.CulException: 我也没办法处理
堆栈信息的打印
import traceback class GenderExcption(Exception): pass class Person: def __init__(self,name,gender): self.name = name self.gender = gender def xizao(self): print(f"{self.name}在洗澡") def nan_zao_tang(ren): if ren.gender == "男": ren.xizao() else: raise GenderExcption("对不起性别不对") try: p1= Person("alex","不知道") p2 = Person("小钱","男") nan_zao_tang(p1) nan_zao_tang(p2) except GenderExcption: ret = traceback.format_exc() #错误信息叫堆栈信息 print(ret) print("出错,走错片场")
打印
Traceback (most recent call last): File "D:/s18/day20约束与异常/异常处理.py", line 60, in <module> nan_zao_tang(p1) File "D:/s18/day20约束与异常/异常处理.py", line 54, in nan_zao_tang raise GenderExcption("对不起性别不对") GenderExcption: 对不起性别不对 出错,走错片场
三.MD5加密
MD5是一种不可逆的加密算法,可靠,安全,在python中不用手写这套方法,只需要调用hashlib这个模块就能搞定
import hashlib obj = hashlib.md5(b'aggagdfhearg') #加盐 obj.update("123456".encode("utf-8")) print(obj.hexdigest())
打印
02fe523c54d362cfa93051f28badd4ea
MD5的应用
import hashlib def my_md5(s): obj = hashlib.md5(b'aggagdfhearg') obj.update(s.encode("utf-8")) return obj.hexdigest() username = "alex" password = "02fe523c54d362cfa93051f28badd4ea"#123 uname = input("请输入用户名") upwd =input("请输入你的密码") if uname == username and my_md5(upwd): print("登录成功") else: print("登录失败")
四.日志
# 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
简单测试
import logging # 配置好日志的处理, 默认就是GBK logging.basicConfig(filename='x1.txt', # 把日志信息写入的文件名 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', # 时间的格式 level=40) # 当前配置表示 10以上的分数会被写入日件 logging.critical("今天嫂子没来")#50 logging.error("昨天嫂子来了")#40 logging.warn("气死了")#30 logging.warning("还好吧")#30 logging.info("提示")#20 logging.debug("开发的时候把这个开着")#10 logging.log(999,"随便定义级别")#自定义
如何分开日志文件
import logging # 创建一个操作日志的对象logger(依赖FileHandler) file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8') # 创建文件 file_handler.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) # 设置日志文件的格式 logger1 = logging.Logger('腾讯qq', level=10) # 创建一个日志文件处理对象 logger1.addHandler(file_handler) # 把文件添加到日志 logger1.error("马画藤请大家吃饭") file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('百度贴吧', level=logging.DEBUG) logger2.addHandler(file_handler2) logger2.error("我才不去吃")
日志的应用
import logging # 创建一个操作日志的对象logger(依赖FileHandler) file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8') # 创建文件 file_handler.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")) # 设置日志文件的格式 logger1 = logging.Logger('腾讯qq', level=10) # 创建一个日志文件处理对象 logger1.addHandler(file_handler) # 把文件添加到日志 logger1.error("马画藤请大家吃饭") file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8') file_handler2.setFormatter(logging.Formatter( fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s")) logger2 = logging.Logger('百度贴吧', level=logging.DEBUG) logger2.addHandler(file_handler2) logger2.error("我才不去吃") import traceback class GenderException(Exception): pass class Person: def __init__(self,name,gender): self.name = name self.gender = gender logger1.info(f"这个人的名字是{self.name}") def xizao(self): print(f"{self.name}在洗澡") class Zaotang: def nan(self,ren): if ren.gender == "男": ren.xizao() else: raise GenderException("我这里要的是男人") def nv(self,ren): if ren.gender == "女": ren.xizao() else: raise GenderException("我这里要的是女人") try: p1 = Person("alex","男") p2 = Person("林志玲","女") zaotang = Zaotang() zaotang.nan(p2) zaotang.nv(p1) except GenderException: print("走错屋了") logger1.error("走错屋了....") logger1.error(traceback.format_exc())