1. 异常处理(处理异常,抛出异常,自定义异常)
   异常: 程序运行过程中产生的错误
   1. 产生异常. raise 异常类(), 抛出异常
   2. 处理异常:
        try:
            xxxxxxxx # 尝试执行的代码.
        except  异常类 as 变量  # 出现错误的时候,捕获到异常
            XXX  # 处理异常
        raise: 抛出异常.
        try:
            可能会出现错误的代码
        except 异常类 as e:
            异常的处理
        except 异常类 as e:
            异常的处理
        except 异常类 as e:
            异常的处理
        except 异常类 as e:
            异常的处理
        else:
            如果上面的代码没有错误, 执行这里的代码
        finally:
            收尾
 
 
   3. 自定义异常
        随便写个类,继承Exception
   4. 堆栈信息
        import traceback
        traceback.format_exc()    # 获取堆栈信息
# 抛出异常
# 计算两个整数的加法
def add(a, b):
    if type(a) != int or type(b) != int:
        # return
        raise TypeError("我这里只要int, 不要别的类型")
    return a + b
add(123, "abc")
 
 
 
![]()
# 程序运行过程中产生的错误, 不正常
def chufa(a, b):
   try: # 尝试执行xxx代码
       ret = a/b # 如果这里出现了错误. 异常. 系统内部会产生一个异常对象. 系统会把这个错误抛出. 抛给调用方
       return ret
   except ZeroDivisionError as e: # 内部产生的ZeroDivisionError异常都会被捕获, 捕获的异常对象会交给e
       print(e)
       print("出错了. 0不能是除数")
   except FileNotFoundError as e:  # 内部产生的FileNotFoundError异常都会被捕获, 捕获的异常对象会交给e
       print(e)
       print("出错了. 0不能是除数")
   except StopIteration as e:  # 内部产生的StopIteration异常都会被捕获, 捕获的异常对象会交给e
       print(e)
       print("出错了. 0不能是除数")
   except Exception as e:  # 内部产生的所有异常都会被捕获, 捕获的异常对象会交给e
       print(e)
       print("出错了. 0不能是除数")
    # .....
ret = chufa(10, 0)
print(ret)
 
异常处理 
# 获取错误堆栈 traceback
import traceback
class GenderError(Exception):
    pass
class Person:
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
def nan_gu_ke_xi_zao(per):
    if per.gender != "男":
        raise GenderError("这里是刘伟的男澡堂子. ")
    else:
        pass
p1 = Person("alex", "不详")
# nan_gu_ke_xi_zao(p1)
p2 = Person("wusir", "不详")
try:
    nan_gu_ke_xi_zao(p2)
except GenderError as g:
    print(g)
    val = traceback.format_exc() # 获取错误堆栈
    print(val)
 
 
 
![]()
import traceback
class GenderError(Exception):
    pass
class Person:
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender
def nan_gu_ke_xi_zao(per):
    if per.gender != "男":
        raise GenderError("这里是刘伟的男澡堂子. ")
    else:
        pass
p1 = Person("alex", "不详")
# nan_gu_ke_xi_zao(p1)
p2 = Person("wusir", "不详")
try:
    nan_gu_ke_xi_zao(p2)
except GenderError as g:
    print(g)
    val = traceback.format_exc() # 获取错误堆栈
    print(val)
 
View Code 
 
 
 
 
2. 约束(难点)
    一. 通过抛异常
        约束是对子类进行的约束
        在父类中给出一个方法,这个方法中什么都不写,只抛异常. NotImplementedError
        在子类中把上述的方法进行重写
        重写: 子类重新定义父类中的方法
    二. 抽象类和抽象方法(java, c#)
            接口:定义方法和约束子类.类中都是抽象方法.
         from abc import ABCMeta, abstractmethod
         抽象方法: 抽象方法不用给出方法体. 写个pass就行了
         抽象类:
            语法:类(metaclass=ABCMeta)
            概念: 如果类中包含了抽象方法,这个类一定是抽象类   抽象方法:@abstractmethod
            特点: 抽象类一般不创建对象.
                  抽象类中可以存在正常方法
         可以约束子类必须实现抽象方法
# 约束,子类若没有重新定义父类中的方法,则按照父类方法抛出异常
class Base:
    def login(self):
        raise NotImplementedError("没有实现login方法") # 专业的写法
    def kantie(self):
        raise NotImplementedError("没有实现看帖功能")
# 张三
class Normal(Base):
    def login(self):
        print("普通人登陆")
# 李四
class Member(Base):
    def denglu(self):
        print("吧务登陆")
# 王五
class Admin(Base):
    def login(self):
        print("管理员登陆")
def login(obj):
    print("产生验证码")
    obj.login() # 标准在这里.  必须有login
    print("进入主页")
# 场景
n = Normal()
m = Member()
a = Admin()
login(n)
login(m)
login(a)
 
 
 
重写:子类对父类提供的方法不满意。 重新去定义这个方法
# 抽象类和抽象方法
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta): # 在父类中写出metaclass= xxx  抽象类, 类中存在抽象方法, 类一定是抽象类
    @abstractmethod # 抽象方法
    def chi(self): # 抽象的概念.
        pass
    def haha(self):     # 可以存在正常方法
        print("娃哈哈")
class Cat(Animal): # 子类必须实现父类中的抽象方法.
    def chi(self):  # 具体的实现
        print("猫爱吃鱼")
    # pass          # 如果没有再子类中重新定义方法,则执行父类中的方法,如果所执行的父类方法是抽象方法,则报错
Cat()
 
 
# 约束,抽象类和抽象方法
from abc import ABCMeta,abstractmethod
class Base(metaclass=ABCMeta):
    @abstractmethod
    def login(self): pass
# 张三
class Normal(Base):
    def login(self):
        print("普通人登陆")
# 李四
class Member(Base):
    def login(self):
        print("吧务登陆")
# 王五
class Admin(Base):
    def login(self):
        print("管理员登陆")
def login(obj):
    print("产生验证码")
    obj.login() # 标准在这里.  必须有login
    print("进入主页")
# 场景
n = Normal()
m = Member()
a = Admin()
login(n)
login(m)
login(a)
 
 
 
3. MD5 加密
    MD5加密:不可逆
    引入模块 hashlib
        1 创建md5对象(实例化)
      obj = hashlib.md5()
        2.把加密信息交给md5对象
      obj.update(bytes)
        3.获取密文
      obj.hexdigest()
import hashlib
# 1. 创建一个MD5对象
obj = hashlib.md5(b"flkjsdalkfjklasdjfklasjkflasdjklfasdjflkadsj") # 加盐
# 2. 把要加密的内容给md5
obj.update("alex".encode("utf-8")) # 必须是字节
# 3. 获取密文
val = obj.hexdigest()   # 534b44a19bf18d20b71ecc4eb77c572f aa7aa5ec13222b27f76a094207c5ac75
print(val)
 
md5模型
def my_md5(val):
    obj = hashlib.md5(b"flkjsdalkfjklasdjfklasjkflasdjklfasdjflkadsj")
    obj.update(val.encode("utf-8"))    
    val = obj.hexdigest()
    return val
 
 
![]()
def my_md5(val):
    obj = hashlib.md5(b"flkjsdalkfjklasdjfklasjkflasdjklfasdjflkadsj")
    obj.update(val.encode("utf-8"))
    val = obj.hexdigest()
    return val
# 注册的时候. 用md5进行加密. 存储的是加密后的密文
username = input("请输入用户名")
password = input("请输入密码")
store = my_md5(password)
print(store)  # alex 26adff81aa6778d26999b95ddc0e50b2
if username == "alex" and my_md5(password) == "26adff81aa6778d26999b95ddc0e50b2":
    print("登录成功")
else:
    print("登录失败")
 
用户登录,密码加密储存 
 
4. 日志处理(重要)
    引入logging模块
   basicConfig
    filename
    format
    datefmt
    简单配置即可(basicConfig 单一日志文件  fileHandler 文件助手可以实现多文件操作)
    日志级别:
        CRITICAL 最高的
        ERRO 40
     WARNING 30
        WARN 30
        INFO 20
        DEBUG 10
        NOTEST 0
import logging
logging.basicConfig(filename='app.log',
                    format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    level=40)    # level 设置级别. 当你的信息的级别>=level的时候才会写入日志文件, 默认30
# CRITICAL = 50
# FATAL = CRITICAL
# ERROR = 40
# WARNING = 30
# WARN = WARNING
# INFO = 20
# DEBUG = 10
# NOTSET = 0
# 写日志
logging.critical("我是critical")
logging.error("我是error")
logging.warning("我是警告")
logging.info("我是基本信息")
logging.debug("我是调试")
logging.log(2, "我是自定义")
 
 
![]()
import logging
import traceback
logging.basicConfig(filename='app.log',
                    format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    level=40)
for i in range(20):
    try:
        if i % 3 == 0:
            raise FileNotFoundError("我是FileNotFountException")
        elif i % 3 == 1:
            raise StopIteration()
        elif i % 3 == 2:
            raise KeyError()
    except FileNotFoundError as e:
        val = traceback.format_exc()
        logging.error(val)
    except StopIteration as e:
        val = traceback.format_exc()
        logging.error(val)
    except KeyError as e:
        val = traceback.format_exc()
        logging.error(val)
    except Exception as e:
        val = traceback.format_exc()
        logging.error(val)
 
日志处理 
# 多文件日志处理
# 创建⼀个操作⽇志的对象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('A', level=40)
logger1.addHandler(file_handler)
# 记录日志
logger1.error('我是A系统')