• 第十九天- 约束 异常处理 日志使用



    # 类的约束:
     1 # 为何要用,在哪里遇到?
     2 
     3 # 例:贴吧登录(若不同人来写)
     4 class Normal:  # 张三版
     5     def login(self):
     6         print("普通账号登录")
     7 
     8 class Member:  # 李四版
     9     def login(self):
    10         print("吧务账号登录")
    11 
    12 class Admin:  # 王二版
    13     def denglu(self):
    14         print("管理员登陆")
    15 
    16 项目经理
    17 def login(obj):
    18     obj.login()
    19 #
    20 n = Normal()
    21 login(n)
    22 
    23 m = Member()
    24 login(m)
    25 
    26 a = Admin()
    27 login(a)  # 报错 'Admin' object has no attribute 'login'
    28 
    29 # 所以有统一调用时,要避免这样的调用不了,要约束程序的结构.也就是说.
    30 # 分配任务之前就应该把功能定义好.然后分别给底下的程序员来完成相应功能
    # 方法一 抛异常 (常用)
    '''
    提取⽗类.然后在⽗类中定义好⽅法.在这个⽅法中什么都不⽤⼲.就抛⼀个异
    常就可以了.这样所有的⼦类都必须重写这个⽅法.否则.访问的时候就会报错.
    (尽量抛出的是NotImplementError. 这样比较专业, ⽽且错误比较明确)
    '''
     1 class Base: # 项目经理 先定好规范
     2     def login(self):  # 强制子类做xxx事情(方法)
     3         raise NotImplementedError("子类没有实现该方法")  # 不做就报错 抛异常
     4 
     5 class Normal(Base):  # 张三版
     6     def login(self):
     7         print("普通账号登录")
     8 
     9 class Member(Base):  # 李四版
    10     def login(self):  # 对login方法的覆盖重写
    11         print("吧务账号登录")
    12 
    13 class Admin(Base):  # 王二版
    14     # def denglu(self):  # 这里方法不是login就没有覆盖   
    15     def login(self):
    16         print("管理员登陆")
    17 
    18 
    19 def login(obj):  # 项目经理调用
    20     obj.login()
    21 
    22 n = Normal()
    23 login(n)  # 当Normal (子类) 去执行login时,先回找自身,自己有所以直接执行,也就不会报错了
    24 
    25 m = Member()
    26 login(m)
    27 
    28 # a = Admin()
    29 # login(a) # 当Admin (子类) 去执行login时,会先回找自身,但他这里自己没有,所以会去父类找login,也就是执行力父类的报错
    30 # 报错 NotImplementedError: 子类没有实现该方法
    31 
    32 a = Admin()
    33 login(a)
    View Code
    # 方案二  写抽象类和抽象⽅法 来约束子类
    '''
    我们如果写⼀个⽅法.不知道⽅法的内部应该到底写什么. 那这个⽅法其实就应该是⼀个抽象的⽅法.
    如果⼀个类中包含抽象⽅法. 那么这个类⼀定是⼀个抽象类.抽象类是不能有实例的.如.你看看⼀些
    抽象派画作.现实中是不存在的.也就⽆法建立实例对象与之相对应.所以抽象类⽆法创建对象.创时会报错
    '''
     1 from abc import  ABCMeta,abstractmethod # 原类 抽象
     2 # 贴吧登录
     3 class Base(metaclass=ABCMeta): # 项目经理 抽象类
     4     @abstractmethod # 抽象方法
     5     def login(self):  # 约束子类
     6         pass
     7 
     8     def hehe(self): # 抽象类中可以有正常方法
     9         print("呵呵呵")
    10 
    11 # b = Base() # 报错的. 原因是Base是一个抽象类. 含有抽象方法. 不允许创建对象的
    12 
    13 
    14 class Normal(Base):  # 张三版
    15     def login(self): # 子类对抽象的内容给出具体的实现 . 重写
    16         print("普通账号登录")
    17 
    18 class Member(Base):  # 李四版
    19     def login(self):  # 子类对抽象的内容给出具体的实现 . 重写
    20         print("吧务账号登录")
    21 
    22 class Admin(Base):  # 王二版
    23     # def denglu(self):  # 报错 继承了前面的抽象必须覆盖
    24     def login(self):
    25         print("管理员登陆")
    26 
    27 
    28 def login(obj):  # 项目经理调用
    29     obj.login()
    30 
    31 
    32 n = Normal()
    33 login(n)
    34 
    35 m = Member()
    36 login(m)
    37 
    38 a = Admin()
    39 login(a)
    View Code
    # 抽象类. 含有抽象方法. 不允许创建对象
    # 一个类如果全部都是抽象方法. 这个类可以被称为接口. 用来约束子类和规范子类
    # 总结
    '''
    当我们需要对子类进行约束:
        1.抛出异常 NotImplementedError()  没有实现   -> 约定俗成.  多观察
        2.写抽象类
            from abc import ABCMeta, abstractmethod
            class Base(metaclass = ABCMeta):
                @abstractmethod
                def 方法(self):
                    pass
            如果一个类中包含了抽象方法. 那么这个类一定是一个抽象类
            一个抽象类中可以包含正常的方法
    
            接口: 接口中所有的方法都是抽象方法
    
            子类必须重写父类中的抽象方法. 否则子类也是一个抽象类
    '''
    View Code


    # 异常处理  try...except
    # 写法(语法)
    try:
    '''操作'''
    except '错误名称' as 别名:
    '''出现错误的时候. 要干什么...'''
    except '错误名称' as 别名:
    '''出现错误的是偶. 要干什么'''
    except Exception as e:
    '''异常的父类,可以捕获所有的异常'''
    else:
    '''保护部抛出异常的代码,当try中无异常时执行'''
    finally:
    '''最后执行这里'''
    '''
    解读:程序先执⾏操作,然后如果出错了会走except中的代码.如果不出错,执⾏else中
    的代码.不论处不出错.最后都要执⾏finally中的语句.⼀般我们⽤try...except就够⽤了.
    顶多加上finally. finally⼀般⽤来作为收尾⼯作.
    '''
    try:
        print(1/0)  #  0不能做除数   ZeroDivisionError: division by zero
    except ZeroDivisionError as z:
        print("错了. 除数不能为0")
    
    
    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,2))
        print(cul(1,"疙瘩汤"))
    
    except Exception as e:
        # 获取错误信息 访问堆栈信息
        print(traceback.format_exc()) # 获取堆栈信息 一般不这么写 装日志
        print("有误")  # 打印是给客户看的
    View Code
    # 日志(固定套路,用时照搬):
    # 1. 导入logging模块.
    # 2. 简单配置⼀下logging
    # 3. 出现异常的时候(except). 向⽇志⾥写错误信息.
     1 import logging
     2 # filename: ⽂件名
     3 # format: 数据的格式化输出. 最终在⽇志⽂件中的样⼦
     4 # 时间-名称-级别-模块: 错误信息
     5 # datefmt: 时间的格式
     6 # level: 错误的级别权重, 当错误的级别权重⼤于等于leval的时候才会写⼊⽂件
     7 logging.basicConfig(filename='x1.log',
     8      format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
     9      datefmt='%Y-%m-%d %H:%M:%S',
    10 level=30)
    11 # 当前配置表示 0以上的分数会被写⼊⽂件
    12 # CRITICAL = 50
    13 # FATAL = CRITICAL
    14 # ERROR = 40
    15 # WARNING = 30
    16 # WARN = WARNING
    17 # INFO = 20
    18 # DEBUG = 10
    19 # NOTSET = 0
    20 logging.critical("我是critical") # 50分. 最贵的
    21 logging.error("我是error") # 40分
    22 logging.warning("我是warning") # 30分
    23 logging.info("我是info")
    24 logging.debug("我是debug")
    25 logging.log(1, "我什么都不是")
    View Code
    1 # 例子,接上面
    2 import traceback
    3 try:
    4     print(1/0)
    5 except Exception:
    6     logging.error(traceback.format_exc()) # 用法
    7     print("出错了")
    View Code
    # 把⽇志⽂件分开 FileHandler
     1 import logging
     2 # 创建⼀个操作⽇志的对象logger(依赖FileHandler)
     3 file_handler = logging.FileHandler('l1.log', 'a', encoding='utf-8')
     4 file_handler.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s"))
     5 logger1 = logging.Logger('A系统', level=logging.ERROR)
     6 logger1.addHandler(file_handler)
     7 logger1.error('我是A系统')
     8 
     9 
    10 # 再创建⼀个操作⽇志的对象logger(依赖FileHandler)
    11 file_handler2 = logging.FileHandler('l2.log', 'a', encoding='utf-8')
    12 file_handler2.setFormatter(logging.Formatter(fmt="%(asctime)s - %(name)s -%(levelname)s -%(module)s: %(message)s"))
    13 logger2 = logging.Logger('B系统', level=logging.ERROR)
    14 logger2.addHandler(file_handler2)
    15 logger2.error('我是B系统')




  • 相关阅读:
    Dijkstra-leetcode 743.网络延迟时间
    BFS-leetcode787 K站中转内最便宜的航班
    图论基础——单源最短路径问题
    DFS leetcode-547 朋友圈
    SpringBoot 使用注解向容器中注册Bean的方法总结
    SpringBoot对SpringMVC的支持
    数据源简介
    Spring MVC简介
    2020-2-10 Python 列表切片陷阱:引用、复制与深复制
    2020-2-2 语法糖
  • 原文地址:https://www.cnblogs.com/xi1419/p/9954776.html
Copyright © 2020-2023  润新知