本节主要内容
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("程序继续知悉个")