• 类的约束异常处理和MD5与日志


    一.类的约束
    首先, 你要清楚. 约束是对类的约束. 比如. 现在. 你是一一个项目目经理理. 然后呢. 你给手手下的人人分活. 张三, 你处理理一一下普通用用户登录, 李四, 你处理理一一下会员登录, 王五, 你处理理一一下管理理员登录. 那这个时候呢. 他们就开始分别取写他们的功能了了. 但是呢. 你要知道, 程序员不一一定会有那么好的默契. 很有可能三个人人会写完全三个不同的方方法. 就比如这样:
    class Normal:# 张三, 普通人人登录
            def login(self):
                pass
    class Member:   # 李李四, 会员登录
            def denglu(self):
                pass
    class Admin:# 王五, 管理理员登录
            def login(self):
                pass
    # 项目目经理理写的总入入口口
    def login(obj):
                print("准备验证码.......")
                obj.login()
                print("进入入主⻚页.......")
    denglu.......难受不. 但是好歹歹能用用. 还能凑合. 但是这时. 你这边要使用用了了. 问题就来了
    在python中遇到类似问题有两种办法解决
            1)提取父父类. 然后在父父类中定义好方方法. 在这个方方法中什什么都不用用干干. 就抛一一个异
    常就可以了了. 这样所有的子子类都必须重写这个方方法. 否则. 访问的时候就会报错
    class Base:
        def login(self):
            raise Exception("你没有实现login方方法()")
    class Normal(Base):
        def login(self):
            pass
    class Member(Base):
        def denglu(self):
            pass
    class Admin(Base):
        def login(self):
            pass
    # 项目目经理理写的总入入口口
    def login(obj):
        print("准备验证码.......")
        obj.login()
        print("进入入主⻚页.......")
    n = Normal()
    m = Member()
    a = Admin()
    login(n)
    login(m)# 报错.
    login(a)
        在执行行行到login(m)的时候程序会报错. 原因是, 此时访问的login()是父父类中的方方法. 但是父父
    类中的方方法会抛出一一个异常. 所以报错. 这样程序员就不得不写login方方法了了. 从而而对子子类进行行行
    了了相应的约束.
    注意exception是所有异常的根,我们无无法通过这个异常来判断出程序是因为什什么报的错. 所以. 最好是换一一个比较专业的错误信息. 最好是换成NotImplementError.其含义是. "没有实现的错误"
            2)使用用元类来描述父父类. 在元类中给出一一个抽象方方法. 这样子子类就不得不给出抽象
    方方法的具体实现. 也可以起到约束的效果.
    第二套方方案: 写抽象类和抽象方方法.
    在python中编写一一个抽象类比较麻麻烦. 需要引入abc模块中的ABCMeta和
    abstractmethod这两个内容.
    from abc import ABCMeta, abstractmethod
    # 类中包含了了抽象方方法. 那此时这个类就是个抽象类. 注意: 抽象类可以有普通方方法
    class IGame(metaclass=ABCMeta):
    # 一一个游戏到底怎么玩儿儿? 你能形容? 流程能一一样么?
    @abstractmethod
        def play(self):
            pass
        def turn_off(self):
            print("破B游戏不不玩了了, 脱坑了了")
        class DNFGame(IGame):
        # 子子类必须实现父父类中的抽象方方法. 否则子子类也是抽象类
            def play(self):
            print("dnf的玩儿儿法")
    # g = IGame() # 抽象类不不能创建对象
    dg = DNFGame()
    dg.play()
    注释:通过代码我们能发现. 这里里里的IGame对DNFGame进行行行了了约束. 换句句话说. 父父类对子子类进
    行行行了了约束.
    from abc import ABCMeta, abstractmethod
    class Base(metaclass=ABCMeta):
        @abstractmethod
        def login(self):
            pass
    class Normal(Base):
        def login(self):pass
    class Member(Base):
        def denglu(self):
            pass
        def login(self):
            pass
    # 这个就没用用了了
    # 子子类对父父类进行行行实现
    class Admin(Base):
        def login(self):
            pass
    # 项目目经理理写的总入入口口
    def login(obj):
        print("准备验证码.......")
        obj.login()
        print("进入入主⻚页.......")
    n = Normal()
    m = Member()
    a = Admin()
    login(n)
    login(m)
    login(a)
    总结: 约束. 其实就是父父类对子子类进行行行约束. 子子类必须要写xxx方方法. 在python中约束的
    方方式和方方法有两种:
        1. 使用用抽象类和抽象方方法, 由于该方方案来源是java和c#. 所以使用用频率还是很少的
        2. 使用用人人为抛出异常的方方案. 并且尽量量抛出的是NotImplementError. 这样比较专
    业, 而而且错误比较明确.(推荐)
    二.异常处理
    指:异常是程序在运行行行过程中产生生的错误.
    def chu(a, b):
        return a/b
    ret = chu(10, 0)
    print(ret)
    输出结果:
    Traceback (most recent call last):
    File "/Users/sylar/PycharmProjects/oldboy/面面向对象/day05.py", line 100, in
    <module>
    ret = chu(10, 0)
    File "/Users/sylar/PycharmProjects/oldboy/面面向对象/day05.py", line 98, in
    chu
    return a/b
    ZeroDivisionError: division by zero
    这个是除数不能为零,在开发过程中这个信息需经过处理才能交给客户
    def chu(a, b):
        return a/b
    try:
        ret = chu(10, 0)
        print(ret)
    except Exception as e:
        print("除数不不能是0")
    结果:
     除数不不能是0
    注释:Exception是所有异常的基类, 也就是异常的跟. 换句句话说. 所有的错误都是Exception的子子类对象. 我们看到的 ZeroDivisionError 其实就是Exception的子子类.
    try:
        print("各种操作....")
    except ZeroDivisionError as e:
        print("除数不不能是0")
    except FileNotFoundError as e:
        print("文文件不不存在")
    except Exception as e:
        print("其他错误")
    
    try:
    '''操作'''
    except Exception as e:
        '''异常的父父类,可以捕获所有的异常'''
    else:
        '''保护不不抛出异常的代码, 当try中无无异常的时候执行行行'''
    finally:
        '''最后总是要执行行行我'''
    
    
    
    def add(a, b):
    '''
    给我传递两个整数. 我帮你计算两个数的和
    :param
    :param a:
    :param
    :param b:
    :return
    :return:
    '''
    if not type(a) == int and not type(b) == int:
        # 当程序运行行行到这句句话的时候. 整个函数的调用用会被中断. 并向外抛出一一个异常.
        raise Exception("不不是整数, 朕不不能帮你搞定这么复杂的运算.")
    return a + b
    # 如果调用用方方不不处理理异常. 那产生生的错误将会继续向外抛. 最后就抛给了了用用户
    # add("你好", "我叫赛利利亚")
    # 如果调用用方方处理理了了异常. 那么错误就不不会丢给用用户. 程序也能正常进行行行
    try:
        add("胡辣汤", "滋滋冒油的大大腰子子")
    except Exception as e:
       print("报错了了. 自自己己处理理去吧")
    三.自定义异常
    自自定义异常: 非常简单. 只要你的类继承了了Exception类. 那你的类就是一一个异常类.
    # 继承Exception. 那这个类就是一一个异常类
    class GenderError(Exception):
    pass
    class Person:
    def __init__(self, name, gender):
    self.name = name
    self.gender = gender
    def nan_zao_tang_xi_zao(person):
    if person.gender != "男":
    raise GenderError("性别不不对. 这里里里是男澡堂子子")
    p1 = Person("alex", "男")
    p2 = Person("eggon", "蛋")
    # nan_zao_tang_xi_zao(p1)
    # nan_zao_tang_xi_zao(p2) # 报错. 会抛出一一个异常: GenderError
    # 处理理异常
    例子一
    try:
        nan_zao_tang_xi_zao(p1)
        nan_zao_tang_xi_zao(p2)
    except GenderError as e:
        print(e) # 性别不不对, 这里里里是男澡堂子子
    except Exception as e:
        print("反正报错了了")
    例子二
    import traceback
    # 继承Exception. 那这个类就是一一个异常类
    class GenderError(Exception):
        pass
    class Person:
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
        def nan_zao_tang_xi_zao(person):
            if person.gender != "男":
                raise GenderError("性别不不对. 这里里里是男澡堂子子")
    p1 = Person("alex", "男")
    p2 = Person("eggon", "蛋")
    # nan_zao_tang_xi_zao(p1)
    # nan_zao_tang_xi_zao(p2) # 报错. 会抛出一一个异常: GenderError
    # 处理理异常
    try:
        nan_zao_tang_xi_zao(p1)
        nan_zao_tang_xi_zao(p2)
    except GenderError as e:
        val = traceback.format_exc() # 获取到堆栈信息
        print(e)
        # 性别不不对. 这里里里是男澡堂子子
        print(val)
    except Exception as e:
        print("反正报错了了")
    结果:
    性别不不对. 这里里里是男澡堂子子
    Traceback (most recent call last):
    File "/Users/sylar/PycharmProjects/oldboy/面面向对象/day05.py", line 155, in
    <module>
    nan_zao_tang_xi_zao(p2)
    File "/Users/sylar/PycharmProjects/oldboy/面面向对象/day05.py", line 144, in
    nan_zao_tang_xi_zao
    raise GenderError("性别不不对. 这里里里是男澡堂子子")
    GenderError: 性别不不对. 这里里里是男澡堂子子
    
    四.MD5加密
    MD5是一一种不可逆的加密算法. 它是可靠的. 并且安全的. 在python
    
    import hashlib
    obj = hashlib.md5()
    obj.update("alex".encode("utf-8")) # 加密的必须是字节
    miwen = obj.hexdigest()
    print(miwen)# 534b44a19bf18d20b71ecc4eb77c572f
    加盐就行行行了,在使用用MD5的时候. 给函数的参数传递一一个byte即可.
    import hashlib
    obj = hashlib.md5(b"fjlksajflkjasfsalwer123dfskjf")
    obj.update("alex".encode("utf-8")) # 加密的必须是字节
    miwen = obj.hexdigest()
    print(miwen)# 99fca4b872fa901aac30c3e952ca786d
    import hashlib
    def my_md5(s):
        obj = hashlib.md5(b"fjlksajflkjasfsalwer123dfskjf")
        obj.update(s.encode("utf-8")) # 加密的必须是字节
        miwen = obj.hexdigest()
        return miwen
    # alex: 99fca4b872fa901aac30c3e952ca786d
    username = input("请输入入用用户名:")
    password = input("请输入入密码:")
    # 数据存储的时候.
    # username: my_md5(password)
    # 加盐# 假设现在的用用户名和密码分别是
    # wusir: 99fca4b872fa901aac30c3e952ca786d
    ==> wusir: alex
    # 用用户登录
    if username == "wusir" and my_md5(password) ==
    "99fca4b872fa901aac30c3e952ca786d":
        print("成功")
    else:
        print("失败")
    
    五.日志
    1. 导入logging模块.
    2. 简单配置一一下logging
    3. 出现异常的时候(except). 向日日志里里里写错误信息.
    
    # 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)
    
    最后, 如果你系统中想要把日日志文文件分开. 比如. 一一个大大项目目, 有两个子子系统, 那两个子子系
    统要分开记录日日志
    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('s1', level=logging.ERROR)
    logger1.addHandler(file_handler)
    logger1.error('我是A系统')# 再创建一一个操作日日志的对象logger(依赖FileHandler)
    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('s2', level=logging.ERROR)
    logger2.addHandler(file_handler2)
    logger2.error('我是B系统')
    

      练习

     项目经理(级别高一点儿)
    class Base:
        def login(self): # 强制子类做xxxx事
            raise NotImplementedError("子类没有实现该方法") # 报错. 抛异常
    
        def verify(self, path):
            username = input("请输入你的用户名")
            password = input("请输入你的密码")
            f = open(path, mode="r", encoding="utf-8")
            for line in f:
                if username + ":" + password == line.strip():
                    print("登录成功")
                    break
            else:
                print("登录失败")
    
    # 1. 普通账号  -->  翔哥
    class Normal(Base):
        def login(self): # 读取普通账户.txt文件
            self.verify("pt.txt")
    
    # 2. 吧务  - > 强哥
    class Member(Base):
        def login(self): # 读取普通账户.txt文件
            self.verify("member.txt")
    
    # 3. 百度员工  -> 明哥
    class Admin(Base):
        def login(self): # 读取普通账户.txt文件
            self.verify("admin.txt")
    
    # 项目经理
    def wodetian(obj):
        obj.login()
    
    n = Normal()
    wodetian(n)
    #
    # m = Member()
    wodetian(m)
    
    a = Admin()
    wodetian(a)
    

      

    植物大战僵尸
    class Base:
        def __init__(self, name, hp, attack):
            self.name = name
            self.hp = hp
            self.attack  = attack
    
        def fight(self, sth):
            if type(self) == type(sth): # 有了阵营. 用类名来确定阵营
                return
            print("%s要打%s了" % (self.name, sth.name))
            js.hp -= self.attack
            print("%s的血量是:%s" % (sth.name, sth.hp))
    
    class Plant(Base):
        pass
    
    class Zombie(Base):
        pass
    
    zw = Plant("豌豆", 100, 5)
    js = Zombie("铁桶僵尸", 5000, 10)
    
    # 同阵营不能攻击
    zw.fight(js)
    zw.fight(js)
    js.fight(zw)
    js.fight(zw)
    js.fight(zw)
    

      

    装空调
    class BanJi:
        def __init__(self,name):
            self.name = name
    
    class KongTiao:
        def __init__(self,name):
            self.name = name
    
    class ShiFu:
        def anzhuang(self, cls, kt):
            print("我要给%s班级装%s空调" % (cls.name, kt.name))
    
    bj = BanJi("火星一班")
    kt = KongTiao("格力28号")
    sf = ShiFu()
    
    
    sf.anzhuang(bj, kt)
    

      

    法题. 青蛙跳井. 青蛙掉井里了.井深200米 每个白天往上跳5米, 晚上往下滑3米,
    	问青蛙几天可以从井里出来. (升级题, 做完上面的题,预习和复习都OK了再想这个)
    
    jingshen = 200
    day = 1
    now = 0
    while 1:
        # 白天
        now += 5
        if now >= jingshen:
            break
        # 晚上
        now -= 3
        day += 1
    
    print(day)
    

      

  • 相关阅读:
    Python 元胞自动机模拟——生命游戏
    ()python画动态图——plt.ion动图使用,训练过程展示
    Python——因子分析(KMO检验和Bartlett's球形检验)
    bind(),unbind(),hover(),toggle(),animate()
    多计算机通信中的时间同步问题
    如何创建自定义尺寸的空白地图
    ROS中的珊格地图——nav_msgs::OccupancyGrid
    c++使用eigen库,矩阵维度错误
    Eigen 求最小二乘
    Mybatis 框架下 SQL 注入攻击的 3 种方式,真是防不胜防!
  • 原文地址:https://www.cnblogs.com/liucsxiaoxiaobai/p/9990215.html
Copyright © 2020-2023  润新知