20.异常 加密 约束
1.
1.昨日内容回顾
1.issnbclass ,type,isinstance
issubclass:判断xxx是xxxx的子类么
type:精准的返回对象的类型
isinstance:判断xxx对象是否是xxx类型的
2.函数和方法
在类外面 都是函数
在类里面
1.实例方法 对象.方法 方法 类名方法 函数
2.静态方法 :都是函数
3.类方法 都是方法
判断的时候
引入types模块中的FunctionType和MethodType 来判断是函数还是方法
isinstance()
3.反射
1.hasattr(obj,str)判断对象中是否包含xxxx(str)
2.getattr(obj,str)从对象中获取xxx(str)
3.setattr(obj,str,value)把对象中的str设置成value
4.delattr(obj,str)从对象中删除xxx(str)
二.今日主要内容
异常处理(处理,抛出异常,自定义异常)
1.产生异常, raise异常类(),抛出异常
2 处理异常
try:
xxxxx #尝试执行的代码
expect 异常类 as变量: #出现错误的时候,捕获到异常
xxxx #处理异常
3.自定义异常
继承 Exception
4.堆栈信息
import traceback
tracaback.formal_exc() 获取堆栈信息
约束(难)
约束是对子类进行的约束
一.通过抛异常(简单)
在父类中给出一个方法,这个方法中什么都不写,就抛异常。NoImplementError()
在子类中把上述的方法进行重写
重写:子类重新定义父类中的方法
二.抽象类和抽象方法
接口:类中都是抽象方法
from abc import ABCMeta,abstractmethod
抽象方法:抽象方法不用给出方法体,写个pass就行了
抽象类:
语法:类(metaclass = ABCMeta )
概念:如果类中包含了抽象方法,这个类一定是抽象类
特点:抽象类一般不创建对象
抽象类中可以存在正常方法
可以约束子类必须实现抽象方法
Md5加密
Md5加密 :不可逆
引入模块 hashlib
1.创建md5对象
2.把加密信息交给md5对象
3.获取密文
日志处理
(重要,简单)
引入logging模块
简单配置即可 (basicConfig 单一日志文件 fileHandle 文件助手可以实现文件操作)
日志级别:
CRITICAL 最高的
error 40
warn 30
info 20
debug = 10
异常处理
异常和抛出异常
1.异常,异常是在程序运行过程中产生的错误 def chu(a,b): return a/b ret = chu(10,0)#如果这里出现了错误,异常 系统会把这个错误抛出,抛给调用方 print(ret)
# def chu(a,b): # return a/b # try: # ret = chu(10,0) # print(ret) # except Exception as e: # print('除数不能是0') #尝试去执行try 里面的代码,出现了错误,就执行except后面的代码 '''原理就是系统产生错误的异常向外抛的时候被except拦截,并赋值 给e。Exception是所有异常的基类,也就是异常的根,所有的异常都可以叫 Exception,比较笼统,所以可以写更多的except'''
捕获异常和处理异常保护程序能够正常运行
捕获异常
def chu(a,b): try: ret = a/b return ret except ZeroDivisionError as e: print(e) print('出错了,0不能是除数') except FileNotFoundError as e: print('出错了,0不能是除数') except StopIteration as e: print('出错了,0不能是除数') except Exception as e: print('除数不能是0') ret = chu(10,0) print(ret) 出现哪个错误就会被相应的except捕获,如果都没出现就会被最后一个Exception try : '''代码操作''' except Exception as e: '''异常的父类,可以捕获所有的异常''' else: '''保护不抛出异常的代码,当try中无异常的时候执行''' finally: '''最后执行的文件''' 在处理异常的过程中会出现一些条件上的不对等,根本不符合 代码逻辑,如何返回给调用方
抛出异常
def add(a,b):
'''传递两个整数,返回代码的和'''
if type(a)!= int and type(b)!= int:
#当程序运行到这个时候,整个函数的调用会被中断。】
# 并向外抛出一个异常
raise Exception('不是整数,我的程序无法帮你搞定')
return a+b
# print(add(1,3))
print(add('nihao','我叫大佬'))
如果调用方不处理异常,产生的错误将会继续向外抛,最后就抛给了用户
如果调用方处理了异常,那么错误就不会传给用户,程序可以正常运行
处理异常
def add(a,b): '''传递两个整数,返回代码的和''' if type(a)!= int and type(b)!= int: #当程序运行到这个时候,整个函数的调用会被中断。】 # 并向外抛出一个异常 raise Exception('不是整数,我的程序无法帮你搞定') return a+b # print(add(1,3)) print(add('nihao','我叫大佬')) # 如果调用方不处理异常,产生的错误将会继续向外抛,最后就抛给了用户 # 如果调用方处理了异常,那么错误就不会传给用户,程序可以正常运行 try : add('nihao','我叫大佬') except Exception as e: print('有错误,自己处理')
在python中可以自定义异常
自定义异常非常简单,只要类继承了 Exception,类就是一个异常类】 # class GenderError(Exception): # pass # class Person: # def __init__(self,name,gender): # self.nmae = name # self.gender = gender # def nan_zao_tang_xi_zao(person): # if person.gender != '男': # raise GenderError('这里不能有女生,男孩子会害羞哒') # else: # pass # p1 = Person('alex','不详') # nan_zao_tang_xi_zao(p1)会抛出一个异常GenderError # 3处理异常 # try: # nan_zao_tang_xi_zao(p1) # except GenderError as g: # print(g) # 这样出现的问题就是调试出来看不到错误源
这样的话调用方看到的是有错误,可是根本不知道错误源
# 这样出现的问题就是调试出来看不到错误源 # 这样的话就需要引入另一个模块 traceback import traceback # 继承Exception,那么这个类就是一个异常类 class GenderError(Exception): pass class Person: def __init__(self,name,gender): self.nmae = name self.gender = gender def nan_zao_tang_xi_zao(person): if person.gender != '男': raise GenderError('这里不能有女生,男孩子会害羞哒') else: pass p1 = Person('alex','不详') # nan_zao_tang_xi_zao(p1)#会抛出一个异常GenderError # 3处理异常 try: nan_zao_tang_xi_zao(p1) except GenderError as g: val = traceback.format_exc()#获取到堆栈信息 # #这样的话测试代码的时候把堆栈信息打印出来,到了线上的生产环境 # # 把这个堆栈去掉 # print(g) # print(val)
约束
调用代码出现的因为名称不同不能调用的示例
# class Normal: # def login(self): # pass #普通登录 # class Member: # def denglu(self): # pass #会员登录 # class Admin: # def login(self): # pass#王五登陆 # # 3三种不同的方式,假如是三个人写的 # def login(obj): # print('准备验证码') # obj.login() # print('进入主页') # n = Normal() # m = Member() # a = Admin() # login(n) # login(m) # login(a) # 这样的话调用不了其中的一个代码,这样的话需要通过约束程序的结构
解决方案
# 也就是说,一开始就需要把功能定义好,
# 两种方法来解决这个问题
'''1.提取父类,然后在父类中定义好方法,在这个方法中什么都不用干,就抛一个
异常,这样的话所有的子类都必须重写这个方法,否则访问就会报错。
2.使用元类来描述父类,在元类中给出一个抽象对象,这样的话子类就不得不
给出抽象方法的具体实现,也可以取到约束的效果'''
第一种解决方案
# 第一种解决方案 # 提取一个父类,在父类中给吃一个方法,并且在方法中不给出任何代码,直接抛异常 class Base: def login(self): raise NotImplementedError('你没有实现我要求的登录方法login()') class Normal(Base): def login(self): pass #普通登录 class Member(Base): def denglu(self): pass #会员登录 class Admin(Base): def login(self): pass#王五 def login(obj): print('准备验证码') obj.login() print('进入主页') n = Normal() m = Member() a = Admin() login(n) login(m) login(a) # 这样的话会很容易的知道程序出的错误是什么错误,容易改
第二种方案
# 写抽象类和抽象方法 # 需要在python中编写一个抽象类比较麻烦,需要引入abc模块中的ABCMeta和absstractmethod 这两个内容 # from abc import ABCMeta,abstractmethod # #类中包含了抽象方法,那么这个类就是抽象类 # class Animal(metaclass = ABCMeta): #在父类中写出metaclass= xxx # # 抽象类, 类中存在抽象方法, 类一定是抽象类 # @abstractmethod # 抽象方法 # def chi(self): # 抽象的概念. # pass # def haha(self): # print("娃哈哈") # class Cat(Animal): # 子类必须实现父类中的抽象方法. # def chi(self): # 具体的实现 # print("猫爱吃鱼") # # c = Cat() # c.chi() # # from abc import ABCMeta,abstractmethod # class Base(metaclass=ABCMeta): # @abstractmethod # def login(self): # pass # class Normal(Base): # def login(self): # pass #普通登录 # class Member(Base): # def denglu(self): # pass #会员登录 # class Admin(Base): # def login(self): # pass#王五 # # def login(obj): # print('准备验证码') # obj.login() # print('进入主页') # n = Normal() # m = Member() # a = Admin() # login(n) # login(m) # login(a) # 会报错,约束其实就是父类对子类的约束,子类必须要写xxx方法, # 在Python中约束的方式和方法有两种 # 1.使用抽象类和抽象方法,该方法来源于Java和c#,使用频率较少 #2.使用人为抛出异常的方案,并且尽量抛出的是NotimplementError # 这样错误比较明显
md5加密
import hashlib obj =hashlib.md5() obj.update('alex'.encode('utf-8')) miwen = obj.hexdigest() print(miwen) # 这样的密文会被破解,不安全 import hashlib obj =hashlib.md5(b'fjeifjeigjeigjejejgejjjg') #创建一个MD5对象 obj.update('alex'.encode('utf-8'))#加密的必须是字节 把要加密的对象传给md5 miwen = obj.hexdigest() #获取密文 print(miwen) #这样的话就不能被破解
# import hashlib
# def my_md5(val):
# obj =hashlib.md5(b'flkjsdalkfjklasdjfklasjkflasdjklfasdjflkadsj')
# obj.update(val.encode('utf-8'))
# val = obj.hexdigest()
# return val
这个模块可以直接复制调用
只用修改val里面传进来的参数,或者修改字符串 但是同一个文件不要修改字符串
实例
import hashlib def my_md5(val): obj =hashlib.md5(b'flkjsdalkfjklasdjfklasjkflasdjklfasdjflkadsj') obj.update(val.encode('utf-8')) val = obj.hexdigest() return val # 注册的时候. 用md5进行加密. 存储的是加密后的密文 username = input("请输入用户名") password = input("请输入密码") cun = my_md5(password) print(cun) # alex 26adff81aa6778d26999b95ddc0e50b2 if username == "alex" and my_md5(password) == "26adff81aa6778d26999b95ddc0e50b2": print("登录成功") else: print("登录失败")
文件日志处理
# 写程序的时候,可能总会出现bug,这些问题一般在测试的时候都要给处理掉,但是有些bug是不一定显示出来的
# 可是还是要在测试的时候解决它
# 需要给所写的程序准备一套日志系统,出现错误的时候,去日志系统里查看,看哪里出现了问题,
# 这样在解决bug的时候就更容易
如何在python中创建日志文档
如何在python中创建日志系统 1.导入logging模块 2.简单配置logging 3.出现异常的时候(except)。向日志里写错误信息 import logging logging.basicConfig(filename='app.log', format='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=0) 设置好就可以写日志 logging.error('你在干什么')
# level 设置级别. 当你的信息的级别>=level的时候才会写入日志文件, 默认30 #filename 文件名 #format 数据的格式化输出,最后在日志中呈现出来的样子 # 时间——名称——级别——模块:错误信息 #datefmt 时间的格式 #leval 错误的级别权重,当错误的级别权重大于等于leval的时候才会写入文件 # 在源码中展示的信息 # CRITICAL = 50 # FATAL = CRITICAL # ERROR = 40 # WARNING = 30 # WARN = WARNING # INFO = 20 # DEBUG = 10 # NOTSET = 0
logging.critical('我是critical') #50 logging.ERROR ('我是ERROR ') logging.WARNING('我是警告') logging.INFO ('我是基本信息 ') logging.DEBUG('我是调试') logging.log(2,'我是自定义') #自定义leval 的值
多系统文件多日志处理
如果系统要把日志文件分开,比如一个大项目,有两个子系统。name这两个
子系统要分开记录日志,方便调试
用上面的basicConfig是不行的,要借助文件助手(FileHander)来帮我们完成日志的分开记录
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('A', level=40) logger1.addHandler(file_handler) # 记录日志 logger1.error('我是A系统') # 再创建⼀个操作⽇志的对象logger(依赖FileHandler) 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('B', level=40) logger2.addHandler(file_handler2) # 记录日志 logger2.error('我是B系统') #
浙公网安备 33010602011771号