一丶约束
建议使用:
class BaseMessage(object): def send(self): """ 必须继承BaseMessage,然后其中必须编写send方法。 用于完成具体业务逻辑。 """ raise NotImplementedError(".send() 必须被重写.") # raise Exception(".send() 必须被重写.")
主动抛出异常的方法,BaseMessage类用于约束,约束其派生类,保证派生类中必须编写send方法,不然执行可能会报错
class BaseMessage(object): def send(self,x1): """ 必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。 """ raise NotImplementedError(".send() 必须被重写.")class Email(BaseMessage): def send(self,x1): """ 必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。 """ passobj = Email()obj.send(1)
抽象和抽象类方法:
from abc import ABCMeta,abstractmethodclass Base(metaclass=ABCMeta): # 抽象类 def f1(self): print(123) @abstractmethod def f2(self): # 抽象方法 passclass Foo(Base): def f2(self): print(666)obj = Foo()obj.f1()
关于其他语言(c#,java):
抽象类抽象方法约束:
abstact class Foo: def f1(self): print(1,3,4) abstact def f2(self):pass class Bar(Foo): def f2(self): print('111')
关于接口约束:
interface IFoo: def f1(self,x1):pass def f2(self,x1):pass interface IBar: def f3(self,x1):pass def f4(self,x1):pass class Foo(IFoo,IBar):# 实现了2个接口 def f1(self,x1):pass def f2(self,x1):pass def f3(self,x1):pass def f4(self,x1):pass
总结:
1.什么是接口以及作用?
接口是一种数据类型,主要用于约束派生类中必须实现指定的方法.
python中不存在,(java,c#中有)
2.python中使用什么来约束?
抽象类-抽象方法 编写麻烦
人为主动抛出异常
3.结束时,抛出异常是否可以用其他的?
不专业: raise Exception(".send() 必须被重写")
专业:raise NotImplentedError(".send() 必须被重写.")
4.应用场景
多个类,内部都必须有某种方法的时候,需要使用基类+异常抛出进行约束
学院管理系统:
class IBase: def login(): raise NotImplementedError(".send() 必须被重写.") class Student: def login(self): pass def score(self): pass class Teacher: def login(self): pass def exam(self): pass class Manager(self): def login(self): pass ....
二丶自定义异常
# 知识点:如何自定义异常类?class MyException(Exception): def __init__(self,code,msg): self.code = code self.msg = msgtry: # 知识点:主动抛出异常 raise MyException(1000,'操作异常')except KeyError as obj: print(obj,1111)except MyException as obj: # 知识点:捕获异常 print(obj,2222)except Exception as obj: print(obj,3333)
# 自定义异常 需要继承Exceptionclass MyException(Exception): def __init__(self, *args): self.args = args# raise MyException('爆出异常')# 常见做法定义异常基类,然后在派生不同类型的异常class loginError(MyException): def __init__(self, code=100, message='登录异常', args=('登录异常',)): self.args = args self.message = message self.code = codeclass loginoutError(MyException): def __init__(self): self.args = ('退出异常',) self.message = '退出异常' self.code = 200# raise loginError() # 这里突然返现 raise引发的异常将中断程序#try: raise loginError()except loginError as e: print(e) # 输出异常 print(e.code) # 输出错误代码 print(e.message) # 输出错误信息
三丶hashlib (加密)
import hashlibSALT = b'2erer3asdfwerxdf34sdfsdfs90'def md5(pwd): # 实例化对象 obj = hashlib.md5(SALT) # 写入要加密的字节 obj.update(pwd.encode('utf-8')) # 获取密文 return obj.hexdigest() # 21232f297a57a5a743894a0e4a801fc3 # 66fbdc0f98f68d69cd458b0cee975fe3 # c5395258d82599e5f1bec3be1e4dea4auser = input("请输入用户名:")pwd = input("请输入密码:")if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a': print('登录成功')else: print('登录失败')
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法.
import hashlib# ######## md5 ########hash = hashlib.md5()# help(hash.update)hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())print(hash.digest())######## sha1 ########hash = hashlib.sha1()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())# ######## sha256 ########hash = hashlib.sha256()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())# ######## sha384 ########hash = hashlib.sha384()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())# ######## sha512 ########hash = hashlib.sha512()hash.update(bytes('admin', encoding='utf-8'))print(hash.hexdigest())以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。import hashlib# ######## md5 ########hash = hashlib.md5(bytes('898oaFs09f', encoding="utf-8"))hash.update(bytes('admin', encoding="utf-8"))print(hash.hexdigest())
python 内置还有一个 hmac模块,他内部对我们创建的key和内容进行进一步处理然后加密
import hmach = hmac.new(bytes('898oaFs09f', encoding="utf-8"))h.update(bytes('admin', encoding="utf-8"))print(h.hexdigest())
四丶logging (日志)
1.单文件日志
import logginglogger = logging.basicConfig(filename='xxxxxxx.txt', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=30)logging.debug('x1') # 10logging.info('x2') # 20logging.warning('x3') # 30logging.error('x4') # 40logging.critical('x5') # 50logging.log(10,'x6')
import tracebackdef func(): try: a = a +1 except Exception as e: # 获取当前错误的堆栈信息 msg = traceback.format_exc() logging.error(msg)func()
注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。
日志格式:
2.多文件日志
对于上述记录日志的功能,只能将日志文件记录到单文件中,如果想设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件 和 日志操作文件
# 定义文件file_1_1 = logging.FileHandler('l1_1.log', 'a', encoding='utf-8')fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s")file_1_1.setFormatter(fmt)file_1_2 = logging.FileHandler('l1_2.log', 'a', encoding='utf-8')fmt = logging.Formatter()file_1_2.setFormatter(fmt)# 定义日志logger1 = logging.Logger('s1', level=logging.ERROR)logger1.addHandler(file_1_1)logger1.addHandler(file_1_2)# 写日志logger1.critical('1111')
# 定义文件file_2_1 = logging.FileHandler('l2_1.log', 'a')fmt = logging.Formatter()file_2_1.setFormatter(fmt)# 定义日志logger2 = logging.Logger('s2', level=logging.INFO)logger2.addHandler(file_2_1)
- 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
- 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
实例:
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('123123123')# 在创建一个操作日志的对象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('666')