一. 类的约束
约束程序的结构, 在分配任务之前就应该把功能定义好, 然后分别交给底下的程序员来完成相应的功能
在python中有两种办法来解决这样的问题
1. 提取父类, 然后在父类中定义好方法, 在方法中抛出一个异常, 这样所有继承父类的子类都必须重写这个方法, 否则访问的时候就会报错
class Base:
def login(self):
raise NotImplementedError # 没有被实现错误, 要求子类必须重写login方法 , 不然抛出异常
class User(Base):
def login(self):
print("用户登陆")
class UserManager(Base):
def login(self):
print("用户管理员登陆")
class Coder(Base):
def login(self):
print("后台程序员登陆")
def func(obj):
obj.login()
u = User()
um = UserManager()
c = Coder()
func(u)
func(um)
func(c)
2. 使用元类来描述父类, 在元类中给出一个抽象方法, 这样子类就不得不给出抽象方法的具体实现, 也可以起到约束的效果, 也就是子类必须重写该方法使之不在抽象, 就可以创建对象了
from abc import ABCMeta, abstractmethod
class Animal(metaclass = ABCMeta):
@abstractmethod
def eat(self):
print("吃什么")
class Cat(Animal):
def eat(self):
print("猫吃鱼")
c = Cat()
c.eat()
抽象方法: 不需要给出具体的方法体, 抽象方法内只写一个pass就行
抽象类: 有抽象方法的类就是抽象类, 抽象类不能创建对象, 抽象类中可以有正常方法
接口: 如果一个类中所有的方法都是抽象方法, 那么这个类就是一个接口
总结: 约束, 就是父类对子类进行约束, 子类必须要重写方法, 在python中约束的方式和方法有两种: (1).使用人为抛出异常的方案, 并且尽量抛出的是NotImplementError, 这样比较专业, 而且错误比较明确(2). 使用抽象类和抽象方法, 由于该方案来源于java和c#, 所以使用频率还是很少的
二. 异常处理
异常就是程序运行时发生错误的信号(在程序出现错误时, 则会产生一个异常, 若程序没有处理它, 则会抛出该异常, 程序的运行也会终止)
错误分为两种: 语法错误和逻辑错误
异常处理语法:
try:
"""操作"""
except ZeroDivisionError ad e:
"""除数不能为0"""
except FileNotFoundError as e:
"""文件不存在"""
except Exception as e:
"""异常的父类, 可以捕获所有的异常"""
else:
""""保护不抛出异常的代码, 当try中无异常的时候执行"""
finally:
"""最后要执行的操作,总会被执行,收尾操作"""
执行流程: 程序先执行操作, 然后如果走错了会走except中的代码, 如果不出错, 执行else中的代码. 无论如何, 程序最后都会执行finally中的语句
自定义异常: 只要你的类继承了Exception类, 那你的类就是一个异常类,
我们在调试的时候, 最好能看到错误源在哪里, 这是需要引入一个模块traceback, 可以获得我们每个方法的调试信息, 又称为堆栈信息, 这个信息对我们排错是很有帮助的
import traceback
class GenderError(Exception):
pass
class Person:
def __init__(self, name, gender):
self.name = name
self.gender = gender
def nan_zao_tang_xi_zao(person):
if person.gender != "男":
raise GenderExceptionError("性别不对, 这里是男澡堂子")
p1 = Person("alex", "男")
p2 = Person("eggon", "蛋")
# 处理异常
try:
nan_zao_tang_xi_zao(p1)
nan_zao_tang_xi_zao(p2)
except GenderError as e:
val = traceback.format_exc() # 获取到堆栈信息
print(e)
print(val) # 打印堆栈信息
except Exception as e:
print("反正报错了")
四. MD5加密
数据库中的密码要以加密的方式存储
MD5算法是一种不可逆的加密算法, 它是可靠地, 安全的. python中只需要引入hashlib模块就能搞定MD5的加密工作
import hashlib
def my_md5(s):
obj = hashlib.md5(b"fasdffgggqgqeger") # 加盐
obj.update(s.encode("utf-8")) # 加密的必须是字节
miwen = obj.hexdigest()
return miwen
username = input("请输入用户名:")
password = input("请输入密码:")
print(my_md5("alex"))
if username == "wusir" and my_md5(password) == "f9a17839b68095c7e847c3b476a0f9fd" :
print("登陆成功")
else:
print("失败")
五. 日志
为了测试不必现的bug, 我们需要给软件准备一套日志系统, 当出现任何错误的时候, 我们都可以去日志系统查询, python中创建日志系统:
1. 导入logging模块
2. 简单配置一下logging
3. 出现异常的时候(except), 向日志里面写错误信息
具体有两种方式:
1. 一个日志文件
import traceback
import logging
logging.basicConfig(filename = "x1.txt",
format = "%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s",
datefmt = "%Y-%m-%d %H:%M:%S",
level = 10)
# file.name 文件名
# format 数据的格式化输出, 最终在日志文件中的样子
# 时间 - 名称 - 级别 - 模块: 错误信息
# datefmt 时间的格式
# level 错误的级别权重, 当错误的级别权重大于等于level的时候才会写入文件
# logging.critical("我是critical") # 50
# logging.ERROR("我是error") # 40
# logging.warning("我是警告") # 30
# logging.info("我是基本信息") # 20
# logging.DEBUG("我是调试") # 10
# logging.log(2, "我是自定义")
class JackError(Exception):
pass
for i in range(5):
try:
if i % 3 == 0:
raise FileNotFoundError
elif i % 3 == 1:
raise KeyError
elif i % 3 == 2:
raise JackError
except FileExistsError:
val = traceback.format_exc()
logging.error(val)
except KeyError:
val = traceback.format_exc()
logging.error(val)
except JackError:
val = traceback.format_exc()
logging.error(val)
except Exception:
val = traceback.format_exc()
logging.error(val)
2. 子系统要分开记录日志, 方便调试, 借助文件助手(FileHandler)
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("s1", level = logging.ERROR)
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("s2", level = logging.ERROR)
logger2.addHandler(file_handler2)
logger2.error("我是B系统")
原文地址:https://www.cnblogs.com/guyannanfei/p/10159177.html