zoukankan      html  css  js  c++  java
  • day19 面向对象05 约束

    1. 约束(1. 抛出异常, 2. 写抽象类)(难点, 重点)
      约束是对类的约束
     方法:

    1. 提取父类, 抛出异常; NotImplementedError
    # 贴吧
    # 项目经理(级别高一点儿)
    class Base:
        def login(self): # 强制子类做xxxx事
            raise NotImplementedError("子类没有实现该方法") # 报错. 抛异常
    
    # 1. 普通账号  -->  翔哥
    class Normal(Base):
        def login(self):
            print("普通账号的登录")
    
    # 2. 吧务  - > 强哥
    class Member(Base):
        def denglu(self):
            print("吧务的登录")
    
    # 3. 百度员工  -> 明哥
    class Admin(Base):
        def login(self): # 方法的覆盖和重写
            print("管理员的登录")
    
    # 项目经理
    def wodetian(obj):
        obj.login()
    
    n = Normal()
    wodetian(n)
    
    m = Member()
    wodetian(m)  # 报错
    View Code
        2. 抽象类
    from abc import ABCMeta, abstractmethod

    class Base(metaclass = ABCMeta): 抽象类

    @abstractmethod
    def 方法(self):pass

    class Foo(Base): 子类必须重写父类中的抽象方法
    def 方法(self):
    pass
    # 在python中可以写出抽象类和抽象方法. 来约束子类
    from abc import ABCMeta, abstractmethod
    # 贴吧
    # 项目经理(级别高一点儿)
    class Base(metaclass=ABCMeta): # 抽象类
        # 抽象方法
        @abstractmethod # staticmethod, classmethod
        def login(self): # 强制子类做xxxx事
            pass
    
        def hehe(self): # 抽象类中可以有正常的方法
            print("我会呵呵呵")
    
    # b = Base() # 报错的. 原因是Base是一个抽象类. 含有抽象方法. 不允许创建对象的
    
    # 一个类如果全部都是抽象方法. 这个类可以被称为接口. 用来约束子类和规范子类
    
    # 1. 普通账号  -->  翔哥
    class Normal(Base):
        pass
        # def login(self): # 重写了父类中的抽象方法
        #     print("普通账号的登录")
    
    n = Normal()  # 不重写抽象的父类方法会报错 TypeError: Can't instantiate abstract class Normal with abstract methods login
    View Code
            一个类包含类抽象方法. 这个类一定是抽象类
    注意: 抽象类中可以有正常类的方法

    抽象类中如果有抽象方法. 这个类将不能创建对象(实例化对象)

    (java和c#的概念) 接口: 类中都是抽象方法

    2. 异常处理
    注意: 程序员是发现不了自己的错误的, 尤其边缘性错误
    完整异常处理写法
    '''
    try:
    xxxx
    except 错误名称 as 别名:
    出现错误的时候. 要干什么...
    except 错误名称 as 别名:
    出现错误的是偶. 要干什么
    ....
    except Exception as e: # 所有错误的根 处理异常的最后的"守门员"
    出现的所有的错误. 我都可以这样处理
    else: # 很少用到
    不出错的时候执行这里的代码
    finally:
    结束. 收尾工作
    '''
    抛出异常: 由python解释器来调用代码, 出现了错误, 系统会自动的产生一个叫异常的对象, 系统会尝试着把错误
         返回给调用方, 这个过程成为:抛出异常
    捕获异常: 通过try...except 可以把系统产生的这个错误进行捕获, 这就是捕获异常

    根据对象的不同, 合理展示错误信息:
    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("出现了错误")  # 反馈给客户的错误信息
    View Code

    自定义异常:
    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("其他错误")
    View Code
    3. 日志处理(logging模块)
    创建日志系统:
      1. 导入logging模块.
      2.
    简单配置⼀下logging
      3.
    出现异常的时候(except). 向⽇志⾥写错误信息
    import logging
    # filename: ⽂件名
    # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦
    # 时间-名称-级别-模块: 错误信息
    # datefmt: 时间的格式
    # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件
    logging.basicConfig(filename='x1.log',
                        format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',  # 重点关注message
                        datefmt='%Y-%m-%d %H:%M:%S',
                        level=0) # 当前配置表示 0以上的分数会被写⼊⽂件   测试环境level设置为10, 上线一般设置为30
    # 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, "我是⾃定义") # ⾃定义.日志的level级别
    
    日志记录异常用法:
    import traceback
    try:
        print(1/0)  
    except Exception:
        logging.error(traceback.format_exc()) 
        print("出错了")
    
    日志文件记录信息:
      File "D:/python_workspace/day019 约束/05 日志处理.py", line 30, in <module>
        print(1/0)
    ZeroDivisionError: division by zero
    
     
    View Code
    
    
    
    
    如果一个项目中, 有两个子系统, 那两个子系统要分开记录日志
    import logging
    # 创建⼀个操作⽇志的对象logger(依赖FileHandler)
    file_handler = logging.FileHandler('zuo.log', 'a', encoding='utf-8')  # open()   文件名可修改
    file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s"))
    
    logger1 = logging.Logger('A系统', 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)
    logger1.error('我是B系统出错了') # 记录日志
    
    # 调用堆栈模块, 既可以拿到错误信息, 又不至于让用户看到错误信息
    import traceback
    try:
        print(1/0)
    except Exception:
        logger2.critical(traceback.format_exc())
        print("出错了. 请联系管理员")
    
    print("程序继续执行")  # 抛出错误后程序继续
    View Code
    
    
    
    
    
  • 相关阅读:
    hiho47 : 拓扑排序·一
    Excel 曝Power Query安全漏洞
    分布式系统技术:存储之数据库
    队列应用
    20155239《Java程序设计》实验一(Java开发环境的熟悉)实验报告
    打印Java main方法执行的命令参数代码
    nothing to commit, working tree clean Remote "origin" does not support the LFS locking API. Consider disabling it with:
    异步
    字节跳动杨震原:A/B测试不是万能的,但不会一定不行
    集成显卡 独显
  • 原文地址:https://www.cnblogs.com/Knight-huang/p/9947799.html
Copyright © 2011-2022 走看看