5.约束与异常处理
一.类的约束
约束是对类的约束
class Base:
#对子类进行约束,必须重写该方法
#以后上班了,拿到公司代码之后,发现NotImplementedError继承它 直接重新写
def login(self):
raise NotImplementedError("你要重新写login方法")
class Member(Base):
def login(self):
print("我是普通人登录")
class Bawu(Base):
def login(self):
print("吧务登录")
class Houtai(Base):
def login(self):
print("后台登录")
#整合这个功能
def deng(obj):
obj.login()
m = Member()
bw = Bawu()
ht = Houtai()
deng(m)
deng(bw)
deng(ht)
python中设置约束的两种方法
1.提取父类,然后在父类中定义好方法,在这个方法中什么都不干直接抛一个异常就可以了,这样所有的子类都必须重写写这个方法,否则访问的时候会报错
2.使用元类来描述父类,在元类中给出一个抽象方法,这样子类不得不给出抽象方法的具体实现,也可以起到约束的效果
在python中写一个抽象类比较麻烦,就需要引入abc模块中的ABCMetea和abstractmethod这两个类容
#导入模块
from abc import ABCMeta ,abstractmethod
#此时抽象类不能创建对象
class Animal(metaclass=ABCMeta): #抽象类
@abstractmethod #抽象方法
def chi(self):pass
#抽象类中可以有正常的方法
def dong(self):
print("动物会动")
class Cat(Animal):
def chi(self): #重写父类中的抽象方法
print("猫喜欢吃鱼")
a = Cat()
a.chi()
a.dong()
总结:约束就是父类对子类进行约束,子类必须写方法
在python中约束的方法和方法有两种:
1.使用抽象类和抽象方法,由于该方案来源于java和c#,所以使用频率低
2.使用人为抛出异常的方案,尽量抛出的是NotImpementError,这样比较专业,而且错误比较明确
二.异常处理
# print(1/0)
# print("哈哈")
抛出异常
Traceback (most recent call last): File "D:/s18/day20约束与异常/异常处理.py", line 3, in <module> print(1/0) ZeroDivisionError: division by zero
怎么解决呢
try:
print(1/0)
except Exception:
print("出错了,出了ZeroDivisionError错误")
print("哈哈")
多个异常的处理方法
try:
print(1/0)
f = open("哈哈哈哈",mode='r')
d = {[]:123}
except ZeroDivisionError:
print("除以0是错的")
except FileNotFoundError:
print("文件不存在的错误")
except Exception:
print("其他错误")
else:
pass
finally:
print("哈哈哈哈哈")
finally:程序报错依然执行以下代码
Exception:万能异常,可以捕获任意异常
自定义异常
class CulException(Exception):
pass
def cul(a,b):
if (type(a)==int or type(a)==float) and (type(b)==int or type(b) == float):
return a+b
else:
raise CulException("我也没办法处理")
print(cul("不放",2))
打印
Traceback (most recent call last): File "D:/s18/day20约束与异常/异常处理.py", line 36, in <module> print(cul("不放",2)) File "D:/s18/day20约束与异常/异常处理.py", line 34, in cul raise CulException("我也没办法处理") __main__.CulException: 我也没办法处理
堆栈信息的打印
import traceback
class GenderExcption(Exception):
pass
class Person:
def __init__(self,name,gender):
self.name = name
self.gender = gender
def xizao(self):
print(f"{self.name}在洗澡")
def nan_zao_tang(ren):
if ren.gender == "男":
ren.xizao()
else:
raise GenderExcption("对不起性别不对")
try:
p1= Person("alex","不知道")
p2 = Person("小钱","男")
nan_zao_tang(p1)
nan_zao_tang(p2)
except GenderExcption:
ret = traceback.format_exc() #错误信息叫堆栈信息
print(ret)
print("出错,走错片场")
打印
Traceback (most recent call last): File "D:/s18/day20约束与异常/异常处理.py", line 60, in <module> nan_zao_tang(p1) File "D:/s18/day20约束与异常/异常处理.py", line 54, in nan_zao_tang raise GenderExcption("对不起性别不对") GenderExcption: 对不起性别不对 出错,走错片场
三.MD5加密
MD5是一种不可逆的加密算法,可靠,安全,在python中不用手写这套方法,只需要调用hashlib这个模块就能搞定
import hashlib
obj = hashlib.md5(b'aggagdfhearg') #加盐
obj.update("123456".encode("utf-8"))
print(obj.hexdigest())
打印
02fe523c54d362cfa93051f28badd4ea
MD5的应用
import hashlib
def my_md5(s):
obj = hashlib.md5(b'aggagdfhearg')
obj.update(s.encode("utf-8"))
return obj.hexdigest()
username = "alex"
password = "02fe523c54d362cfa93051f28badd4ea"#123
uname = input("请输入用户名")
upwd =input("请输入你的密码")
if uname == username and my_md5(upwd):
print("登录成功")
else:
print("登录失败")
四.日志
# filename: ⽂文件名
# format: 数据的格式化输出. 最终在日志⽂文件中的样子
# 时间-名称-级别-模块: 错误信息
# datefmt: 时间的格式
# level: 错误的级别权重, 当错误的级别权重大于等于leval的时候才会写入⽂文件
logging.basicConfig(filename='x1.txt',
format='%(asctime)s - %(name)s - %(levelname)s -% (module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
level=0) # 当前配置表示 10以上的分数会被写入文件
# CRITICAL = 50
# FATAL = CRITICAL
# ERROR = 40
# WARNING = 30
# WARN = WARNING
# INFO = 20
# DEBUG = 10
# NOTSET = 0 logging.critical("我是critical")# 50. 最高的
# logging.error("我是error") # 40
简单测试
import logging
# 配置好日志的处理, 默认就是GBK
logging.basicConfig(filename='x1.txt', # 把日志信息写入的文件名
format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S', # 时间的格式
level=40) # 当前配置表示 10以上的分数会被写入日件
logging.critical("今天嫂子没来")#50
logging.error("昨天嫂子来了")#40
logging.warn("气死了")#30
logging.warning("还好吧")#30
logging.info("提示")#20
logging.debug("开发的时候把这个开着")#10
logging.log(999,"随便定义级别")#自定义
如何分开日志文件
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('腾讯qq', level=10) # 创建一个日志文件处理对象
logger1.addHandler(file_handler) # 把文件添加到日志
logger1.error("马画藤请大家吃饭")
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('百度贴吧', level=logging.DEBUG)
logger2.addHandler(file_handler2)
logger2.error("我才不去吃")
日志的应用
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('腾讯qq', level=10) # 创建一个日志文件处理对象
logger1.addHandler(file_handler) # 把文件添加到日志
logger1.error("马画藤请大家吃饭")
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('百度贴吧', level=logging.DEBUG)
logger2.addHandler(file_handler2)
logger2.error("我才不去吃")
import traceback
class GenderException(Exception):
pass
class Person:
def __init__(self,name,gender):
self.name = name
self.gender = gender
logger1.info(f"这个人的名字是{self.name}")
def xizao(self):
print(f"{self.name}在洗澡")
class Zaotang:
def nan(self,ren):
if ren.gender == "男":
ren.xizao()
else:
raise GenderException("我这里要的是男人")
def nv(self,ren):
if ren.gender == "女":
ren.xizao()
else:
raise GenderException("我这里要的是女人")
try:
p1 = Person("alex","男")
p2 = Person("林志玲","女")
zaotang = Zaotang()
zaotang.nan(p2)
zaotang.nv(p1)
except GenderException:
print("走错屋了")
logger1.error("走错屋了....")
logger1.error(traceback.format_exc())

浙公网安备 33010602011771号