zoukankan      html  css  js  c++  java
  • day019类的约束,异常处理,日志

    本节主要内容

    1.类的约束(重点掌握)
    2.异常处理及自定义异常
    3.日志

    一、类的约束(两种约束方法)

    1.抛出异常
    2.抽象类(跟其他语言相似)

    1、抛出异常

    抛出 Implemented,
    class 父类名:  # 写个父类让子类继承
        def 方法名():  # 强制子类做某事
            raise NotImplementedError("子类未实现xxx功能") # 报错抛异常

    fe:具体写法

    # 约束的方法一: 抛异常
    # 一般由项目经理(级别高的人)写约束
    
    # 先写个约束的父类,子类继承父类,未覆盖父类的方法,就会抛异常
    class Base:
        def login(self):        # 强制子类做某事
            raise NotImplementedError("子类没有实现login功能")  # 报错,抛异常
    
    # 1.普通登录,
    class Normal(Base):
        def login(self):
            print("这是普通用户登录")
    
    # 2.吧务登录
    class Member(Base):
        def login(self):
            print("这是吧务登录")
    
    # 管理员登录
    class Admin(Base):
        def denglu(self): # 子类没有覆盖父类的方法,会报错,你没有实现父类要求的功能(方法)
            print("这是管理员登录")
    
    # 项目经理的总入口
    def test(obj):
        obj.login()
    
    a = Admin()
    test(a)

    2、抽象类

    语法:
    from abc improt ABCMeta, abstractmethod
    class 抽象类名(metaclass = ABCMeta):  # 抽象类
        @abstractmethod
        def 方法(self): pass # 抽象方法
    
    class Foo(Base):
        def 方法(self):  # 子类必须重写父类的抽象方法,否则子类也是抽象类
            pass

    1、相关结论

    1.子类必须重写父类的抽象方法,否则子类也是抽象类
    2.抽象类不能创建对象
    3.有抽象方法的类,就是抽象类
    4.抽象类可以有普通方法
    5.接口:接口所有方法都是抽象方法,(引用其他语言,python自己没有定义这一条)

    fe:

    from abc import ABCMeta, abstractmethod  # 引入抽象模块
    
    class Animal(metaclass = ABCMeta): # 抽象类
        @abstractmethod  # 抽象方法
        def chi(self):  # 抽象的概念
            pass
    
    class Cat(Animal):  # 子类
        def chi(self):   # 子类对抽象的内容给出具体的实现 . 重写
            print("猫用嘴吃,")
    
    c = Cat()
    c.chi()
    
    a = Animal()   # 报错,抽象类不能创建对象(不能实例化对象)

    二、异常处理及自定义异常

    由python解释器来调用代码. 出现了错误. 系统会自动的产生一个叫异常的对象.
    系统会尝试着把错误返回给调用方. 过程被称为:抛异常
    我们通过try...except 可以吧系统产生的这个错误获取到. 过程叫捕获异常
    我们对异常进行处理,返回让用户看的懂的异常信息
    自己也在这个过程中,用improt traceback 获得堆栈信息(给程序员排错用的)

    1、异常处理的写法

    1.只对异常处理,不获取堆栈信息

    try:
        xxxx
    except 错误名称 as 别名:
        出现错误的时候. 要干什么...
    except 错误名称 as 别名:
        出现错误的是偶. 要干什么
    ....
    except Exception as e: # 所有错误的根
        出现的所有的错误. 我都可以这样处理
    else: # 很少用到
        不出错的时候执行这里的代码
    finally:
        结束. 收尾工作

    2.对异常处理,并获取堆栈信息

    import traceback
    try:
        # 尝试执行的代码
    except Exception as e:
        # 出了错之后要做什么
        traceback.format_exc() # 获取堆栈信息(错误信息)

    fe1:第一种处理

    try:
        print(1/0) #  0不能做除数   ZeroDivisionError: division by zero
    except ZeroDivisionError as z:  # 拦截ZeroDivisionError,处理后返回给客户
        print("错了. 除数不能为0")

    fe2:第二种处理

    import traceback
    # 计算a+b
    def cul(a, b):
        if (type(a) == int or type(a) == float) and (type(b) == int or type(b) == float):
            return a + b
        else:
            # 在这里有两种方案.
            # 1. 直接返回 (不够人性化),
            # 2. 抛出异常: raise 抛出 Exception 错误和异常,所有错误的根
    
            raise Exception("我要的不是这个. 你应该我传递int或者float")
    
    try:
        print(cul(1, "胡辣汤")) # 加上异常的处理
    except Exception as e:
        # 获取到错误信息. 我们需要访问堆栈信息
        print(traceback.format_exc()) # 获取堆栈信息
        print("出现了错误")

    2、自定义异常

    我们在自定义会出现的错误:
    因为python中没有给出具体的记录, 慎用. 名字一定要符合规范

    1、写法

    class GenderException(Exception):   # 自定义错误名字,继承父类Exception,除了名字以外都是父类中的Exception
        pass

    fe:自定义的示例

    class GenderException(Exception):
        pass
    
    class Person:
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
        #  洗澡 -> 男的进男浴室
        def goto_nan_yushi(self):
            if self.gender != "男":
                raise GenderException("性别不对") # 除了名字以外都是父类中的Exception
            else:
                print("欢迎光临.")
    try:
        p2 = Person("wusir", "女")   # 报错了就不在执行下面的内容了
        p2.goto_nan_yushi()
        p1 = Person("alex", "男")
        p1.goto_nan_yushi()
    except GenderException as e:
        print("你去男澡堂子干嘛?")
    except Exception as e:
        print("其他错误")

    三、日志

    日志一般一个公司只用一套,拿来知道要修改什么位置的信息就行,
    不需要记,不需要写,知道原理,会调用就行

    1、在Python创建日志系统

    1. 导入logging模块.
    2. 简单配置⼀下logging
    3. 出现异常的时候(except). 向⽇志⾥写错误信息.

    2、只能写到一个日志文件的日志方法

    import logging
    # filename: ⽂件名
    # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦
    # 时间-名称-级别-模块: 错误信息
    # datefmt: 时间的格式
    # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件
    logging.basicConfig(filename='x1.log',
         format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
         datefmt='%Y-%m-%d %H:%M:%S',
    level=0)
    # 当前配置表示 0以上的分数会被写⼊⽂件
    # 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("我是warning")
    logging.info("我是info")
    logging.debug("我是debug")
    logging.log(1, "我什么都不是")
    
    import traceback
    try:
        print(1/0)
    except Exception:
        logging.error(traceback.format_exc()) # 用法
        print("出错了")

    3、分开记录日志的方法

    一个大项目,分两个子系统,需要分开记录,我们需要借助文件助手(FileHandler)
    import logging
    # 创建⼀个操作⽇志的对象logger(依赖FileHandler)
    #                       open()
    file_handler = logging.FileHandler('zuo.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=20)
    logger1.addHandler(file_handler) # 把文件助手和日志对象绑定
    logger1.error('我是A系统出错了') # 记录日志
    
    
    # 再创建⼀个操作⽇志的对象logger(依赖FileHandler)
    file_handler2 = logging.FileHandler('you.log', 'a', encoding='utf-8')
    file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s"))
    logger2 = logging.Logger('B系统', level=20)
    logger2.addHandler(file_handler2)
    
    
    import traceback
    try:
        print(1/0)
    except Exception:
        logger2.critical(traceback.format_exc())
        print("出错了. 请联系管理员")
    print("程序继续知悉个")
  • 相关阅读:
    【HYSBZ】1588 营业额统计
    【HYSBZ】1503 郁闷的出纳员
    【ZOJ】3228 Searching the String
    【ZOJ】3494 BCD Code
    【HDU】1754 I Hate It
    【HDU】3247 Resource Archiver
    【POJ】3481 Double Queue
    EdgeCore初学习
    go mod常用命令 已经 常见问题
    GO语言内存操作指导—unsafe的使用
  • 原文地址:https://www.cnblogs.com/yipianshuying/p/9947450.html
Copyright © 2011-2022 走看看