20_异常处理相关
一、类的约束
要约束程序的结构,再分配任务时要把功能定义好,然后交给 程序员分别完成相应的功能。
1、提取父类 -- 然后在父类中定义好方法. 在这个方法中什么都不用干. 就抛一个异常就可以了. 这样所有的子类都必须重写这个方法. 否则访问的时候就会报错
第一种解决方案: 首先, 提取一个父类. 在父类中给出一个方法. 并且在方法中不给出任何代码. 直接抛异常.
1 class Base: 2 def login(self): 3 raise Exception("你没有实现login方法()") Exception是所有异常的根.(不好,无法判断出的什么错),专业的NotImplementError(没有实现的错误) 4 class Normal(Base): 5 def login(self): 6 pass 7 class Member(Base): 8 def denglu(self): 9 pass 10 class Admin(Base): 11 def login(self): 12 pass 13 14 # 项目经理理写的总入口 15 def login(obj): 16 print("准备验证码.......") 17 obj.login() 18 print("进入主页.......") 19 n = Normal() 20 m = Member() 21 a = Admin() 22 login(n) 23 login(m) # 报错. 24 login(a)
在执行到login(m)的时候程序会报错. 原因是, 此时访问的login()是父类中的方法. 但是父类中的方法会抛出一个异常. 所以报错. 这样程序员就不得不写login方法了. 从而对子类进行了相应的约束.
2、抽象类 -- 写抽象类和抽象⽅法
抽象:动物的吃,一个动物到底怎么吃,描述不清。只有一个动作的概念,没有具体实现。
一个类中含有抽象方法,那么这个类一定是抽象类,抽象类是不能有实例的(创建对象),比如抽象画,在现实世界找不到。、
抽象类实现
1 from abc import ABCMeta, abstractmethod 2 #注意,Python中抽象类中可以含有普通方法 3 4 class IGame(metaclass = ABCMeta): 5 @abstractmethod 6 def play(self): 7 pass 8 9 def turn_off(self): 10 print("ko") 11 12 class DNFGame(IGame): # 子类必须实现父类中的抽象方法,否则子类也是抽象类 13 def play(self): 14 print("dnf的玩法") 15 16 dg = DNFGame() 17 dg,play()
总结:
约束,其实就是父类对子类进行约束. 子类必须要写xxx方法. 在python中约束的方式和方法有两种: 1. 使用抽象类和抽象方法, 由于该方案来源是java和c#. 所以使用频率还是很少的 2. 使用人为抛出异常的方案. 并且尽量抛出的是NotImplementError. 这样比较专业, 而且错误比较明确.(推荐)
二、异常处理
1、基本异常
1 def chu(a, b): 2 return a/b 3 try: ret = chu(10, 0) 4 print(ret) 5 except Exception as e: 6 print("除数不不能是0") 7 8 结果: 除数不不能是0
尝试着运行xxxxx代码. 出现了错误. 就执行except后面的代码. 在这个过程中. 当代码出现错误的时候. 系统会产生一个异常对象. 然后这个异常会向外抛. 被except拦截. 并把接收到的异常对象赋值给e. 那这里的e就是异常对象. Exception是所有异常的基类。
1 try: print("各种操作....") 2 except ZeroDivisionError as e: 3 print("除数不不能是0") 4 except FileNotFoundError as e: 5 print("文件不不存在") 6 except Exception as e: 7 print("其他错误")
完整的
1 try: 2 '''操作''' 3 except Exception as e: 4 '''异常的父类,可以捕获所有的异常''' 5 else: 6 '''保护不不抛出异常的代码, 当try中无异常的时候执行行''' 7 finally: # finally一般用来作为收尾工作 8 '''最后总是要执行行我'''
2、抛出异常 -- raise关键字
1 def add(a, b): 2 ''' 3 给我传递两个整数. 我帮你计算两个数的和 4 :param :param a: 5 :param :param b: 6 :return :return: 7 ''' 8 if not type(a) == int and not type(b) == int: # 当程序运到这句话的时候. 整个函数的调会被中断. 并向外抛出个异常. 9 raise Exception("不是整数, 朕不能帮你搞定这么复杂的运算.") 10 return a + b # 如果调不处理异常. 那产的错误将会继续向外抛. 最后就抛给了户 11 12 # add("你好", "我叫赛利亚") 13 # 如果调处理了异常. 那么错误就不会丢给户. 程序也能正常进 14 try: 15 add("胡辣汤", "滋滋冒油的腰") 16 except Exception as e: 17 print("报错了. 处理去吧")
当程序运到raise. 程序会被中断. 并实例化后的异常对象. 抛给调用方. 如果调用方不处理. 则会把错误继续向上抛出. 最终抛给户. 如果调用方处理了异常. 那程序可以正常的执行.
3、自定义异常
只要继承了Exception类,那这个类就是异常类
1 import traceback 2 class GenderError(Exception): 3 pass 4 5 class Person: 6 def __init__(self, name, gender): 7 self.name = name 8 self.gender = gender 9 10 def nan_gu_ke_xi_zao(per): 11 if per.gender != "男": 12 raise GenderError("这里是XX的男澡堂子. ") 13 else: 14 pass 15 p1 = Person("alex", "不详") 16 # nan_gu_ke_xi_zao(p1) 17 p2 = Person("wusir", "不详") 18 try: 19 nan_gu_ke_xi_zao(p2) 20 except GenderError as g: 21 print(g) 22 val = traceback.format_exc() # 获取错误堆栈 23 print(val)
MD5是一种不可逆的加密算法
1 1、普通 2 import hashlib 3 obj = hashlib.md5() 4 obj.update("alex".encode("utf-8")) # 加密的必须是字节 5 miwen = obj.hexdigest() 6 print(miwen) # 534b44a19bf18d20b71ecc4eb77c572f 7 8 2、高级 9 import hashlib 10 obj = hashlib.md5(b"fjlksajflkjasfsalwer123dfskjf") # 加盐 11 obj.update("alex".encode("utf-8")) # 加密的必须是字节 12 miwen = obj.hexdigest() 13 print(miwen) # 99fca4b872fa901aac30c3e952ca786d 14 15 3、MD5应用 16 import hashlib 17 def my_md5(s): 18 obj = hashlib.md5(b"fjlksajflkjasfsalwer123dfskjf") 19 obj.update(s.encode("utf-8")) # 加密的必须是字节 20 miwen = obj.hexdigest() 21 return miwen 22 # alex: 99fca4b872fa901aac30c3e952ca786d 23 username = input("请输⼊⽤户名:") 24 password = input("请输⼊密码:") 25 # 数据存储的时候. 26 # username: my_md5(password) 27 # 假设现在的⽤户名和密码分别是 28 # wusir: 99fca4b872fa901aac30c3e952ca786d ==> wusir: alex 29 # ⽤户登录 30 if username == "wusir" and my_md5(password) == "99fca4b872fa901aac30c3e952ca786d": 31 print("成功") 32 else: 33 print("失败")
日志处理
1 # filename: ⽂件名 2 # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦ 3 # 时间-名称-级别-模块: 错误信息 4 # datefmt: 时间的格式 5 # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件 6 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以上的分数会被写⼊⽂件 7 # CRITICAL = 50 8 # FATAL = CRITICAL 9 # ERROR = 40 10 # WARNING = 30 11 # WARN = WARNING 12 # INFO = 20 13 # DEBUG = 10 14 # NOTSET = 0 15 logging.critical("我是critical") # 50分. 最贵的 16 logging.error("我是error") # 40分 17 logging.warning("我是警告") # 警告 30 18 logging.info("我是基本信息") # 20 19 logging.debug("我是调试") # 10 20 logging.log(2, "我是⾃定义") # ⾃定义. 看着给分