Python基础20_类的约束,异常处理,MD5加密,日志

 一. 类的约束
    约束程序的结构, 在分配任务之前就应该把功能定义好, 然后分别交给底下的程序员来完成相应的功能
    在python中有两种办法来解决这样的问题
    1. 提取父类, 然后在父类中定义好方法, 在方法中抛出一个异常, 这样所有继承父类的子类都必须重写这个方法, 否则访问的时候就会报错
    class Base:
        def login(self):
            raise NotImplementedError   # 没有被实现错误, 要求子类必须重写login方法 , 不然抛出异常

    class User(Base):
        def login(self):
            print("用户登陆")

    class UserManager(Base):
        def login(self):
            print("用户管理员登陆")

    class Coder(Base):
        def login(self):
            print("后台程序员登陆")

    def func(obj):
        obj.login()

    u = User()
    um = UserManager()
    c = Coder()

    func(u)
    func(um)
    func(c)
    2. 使用元类来描述父类, 在元类中给出一个抽象方法, 这样子类就不得不给出抽象方法的具体实现, 也可以起到约束的效果, 也就是子类必须重写该方法使之不在抽象, 就可以创建对象了
    from abc import ABCMeta, abstractmethod

    class Animal(metaclass = ABCMeta):
        @abstractmethod
        def eat(self):
            print("吃什么")

    class Cat(Animal):
        def eat(self):
            print("猫吃鱼")

    c = Cat()
    c.eat()
    抽象方法: 不需要给出具体的方法体, 抽象方法内只写一个pass就行
    抽象类: 有抽象方法的类就是抽象类, 抽象类不能创建对象, 抽象类中可以有正常方法
    接口: 如果一个类中所有的方法都是抽象方法, 那么这个类就是一个接口
    总结: 约束, 就是父类对子类进行约束, 子类必须要重写方法, 在python中约束的方式和方法有两种: (1).使用人为抛出异常的方案, 并且尽量抛出的是NotImplementError, 这样比较专业, 而且错误比较明确(2). 使用抽象类和抽象方法, 由于该方案来源于java和c#, 所以使用频率还是很少的
二. 异常处理   点击了解详情
    异常就是程序运行时发生错误的信号(在程序出现错误时, 则会产生一个异常, 若程序没有处理它, 则会抛出该异常, 程序的运行也会终止)
    错误分为两种: 语法错误和逻辑错误
    异常处理语法: 
    try: 
        """操作"""
    except     ZeroDivisionError ad e:
        """除数不能为0"""
    except FileNotFoundError as e:
        """文件不存在"""
    except Exception as e:
        """异常的父类, 可以捕获所有的异常"""
    else:
        """"保护不抛出异常的代码, 当try中无异常的时候执行"""
    finally:
        """最后要执行的操作,总会被执行,收尾操作"""
    执行流程: 程序先执行操作, 然后如果走错了会走except中的代码, 如果不出错, 执行else中的代码. 无论如何, 程序最后都会执行finally中的语句
    自定义异常: 只要你的类继承了Exception类, 那你的类就是一个异常类,
    我们在调试的时候, 最好能看到错误源在哪里, 这是需要引入一个模块traceback, 可以获得我们每个方法的调试信息, 又称为堆栈信息, 这个信息对我们排错是很有帮助的
    import traceback

    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 GenderExceptionError("性别不对, 这里是男澡堂子")

    p1 = Person("alex", "男")
    p2 = Person("eggon", "蛋")

    # 处理异常
    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("反正报错了")    
四. MD5加密
    数据库中的密码要以加密的方式存储
    MD5算法是一种不可逆的加密算法, 它是可靠地, 安全的. python中只需要引入hashlib模块就能搞定MD5的加密工作    
    import hashlib

    def my_md5(s):
        obj = hashlib.md5(b"fasdffgggqgqeger")        # 加盐
        obj.update(s.encode("utf-8"))                # 加密的必须是字节
        miwen = obj.hexdigest()
        return miwen

    username = input("请输入用户名:")
    password = input("请输入密码:")
    print(my_md5("alex"))

    if username == "wusir" and my_md5(password) == "f9a17839b68095c7e847c3b476a0f9fd" :
        print("登陆成功")
    else:
        print("失败")
五. 日志
    为了测试不必现的bug, 我们需要给软件准备一套日志系统, 当出现任何错误的时候, 我们都可以去日志系统查询, python中创建日志系统:
    1. 导入logging模块
    2. 简单配置一下logging
    3. 出现异常的时候(except), 向日志里面写错误信息
    具体有两种方式:
    1. 一个日志文件
    import traceback  点击了解traceback详情
    import logging
    
    logging.basicConfig(filename = "x1.txt",
                        format = "%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s",
                        datefmt = "%Y-%m-%d %H:%M:%S",
                        level = 10)
    # file.name 文件名
    # format 数据的格式化输出, 最终在日志文件中的样子
    #     时间 - 名称 - 级别 - 模块: 错误信息
    # datefmt 时间的格式
    # level 错误的级别权重, 当错误的级别权重大于等于level的时候才会写入文件
    # 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(5):
        try:
            if i % 3 == 0:
                raise FileNotFoundError
            elif i % 3 == 1:
                raise KeyError
            elif i % 3 == 2:
                raise JackError
        except FileExistsError:
            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)
    2. 子系统要分开记录日志, 方便调试, 借助文件助手(FileHandler)
    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系统")
         

六、python所有的标准异常类:

异常名称描述
BaseException 所有异常的基类
SystemExit 解释器请求退出
KeyboardInterrupt 用户中断执行(通常是输入^C)
Exception 常规错误的基类
StopIteration 迭代器没有更多的值
GeneratorExit 生成器(generator)发生异常来通知退出
SystemExit Python 解释器请求退出
StandardError 所有的内建标准异常的基类
ArithmeticError 所有数值计算错误的基类
FloatingPointError 浮点计算错误
OverflowError 数值运算超出最大限制
ZeroDivisionError 除(或取模)零 (所有数据类型)
AssertionError 断言语句失败
AttributeError 对象没有这个属性
EOFError 没有内建输入,到达EOF 标记
EnvironmentError 操作系统错误的基类
IOError 输入/输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块/对象失败
KeyboardInterrupt 用户中断执行(通常是输入^C)
LookupError 无效数据查询的基类
IndexError 序列中没有没有此索引(index)
KeyError 映射中没有这个键
MemoryError 内存溢出错误(对于Python 解释器不是致命的)
NameError 未声明/初始化对象 (没有属性)
UnboundLocalError 访问未初始化的本地变量
ReferenceError 弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError 一般的运行时错误
NotImplementedError 尚未实现的方法
SyntaxError Python 语法错误
IndentationError 缩进错误
TabError Tab 和空格混用
SystemError 一般的解释器系统错误
TypeError 对类型无效的操作
ValueError 传入无效的参数
UnicodeError Unicode 相关的错误
UnicodeDecodeError Unicode 解码时的错误
UnicodeEncodeError Unicode 编码时错误
UnicodeTranslateError Unicode 转换时错误
Warning 警告的基类
DeprecationWarning 关于被弃用的特征的警告
FutureWarning 关于构造将来语义会有改变的警告
OverflowWarning 旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning 关于特性将会被废弃的警告
RuntimeWarning 可疑的运行时行为(runtime behavior)的警告
SyntaxWarning 可疑的语法的警告
UserWarning 用户代码生成的警告

        

posted @ 2018-12-21 21:59  lokichoggio  阅读(173)  评论(0编辑  收藏  举报