一 . 约束
class BaseMessage(object): def send(self,x1): """ 必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。 """ raise NotImplementedError(".send() 必须被重写.") class Email(BaseMessage): def send(self,x1): """ 必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。 """ pass obj = Email() obj.send(1)
约束有两种方法 :
-- 抽象类 + 抽象方法 编写上麻烦
-- 人为主动抛出异常
class BaseMessage(object): def send(self,x1): """ 必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。 """ raise NotImplementedError(".send() 必须被重写.") class Email(BaseMessage): def send(self,x1): """ 必须继承BaseMessage,然后其中必须编写send方法。用于完成具体业务逻辑。 """ print('发送邮件') obj = Email() obj.send(1)
from abc import ABCMeta,abstractmethod class Base(metaclass=ABCMeta): # 抽象类 def f1(self): print(123) @abstractmethod def f2(self): # 抽象方法 pass class Foo(Base): def f2(self): print(666) obj = Foo() obj.f1()
接口是一种数据类型,主要用于约束派生类中必须实现指定的方法
python中不存在,Java和C# 中是存在接口的
python中是用约束来实现接口的
接口,接口中不允许在方法内部写代码,只能约束继承它的类必须实现接口中定义的所有方法
class IFoo: def f1(self, x1): pass def f2(self, x1): pass class 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
总结 : 约束时 , 用NotImplementedError比Exception更专业
主要应用在多个类,内部必须都有某些方法时,需要使用基类 + 异常进行约束
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 = msg try: # 知识点:主动抛出异常 raise MyException(1000,'操作异常') except KeyError as obj: print(obj,1111) except MyException as obj: # 知识点:捕获异常 print(obj,2222) except Exception as obj: print(obj,3333)
def func(path,prev): """ 去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。 1000,成功 1001,文件不存在 1002,关键字为空 1003,未知错误 ... :return: """ response = {'code':1000,'data':None} try: if not os.path.exists(path): response['code'] = 1001 response['data'] = '文件不存在' return response if not prev: response['code'] = 1002 response['data'] = '关键字为空' return response pass except Exception as e: response['code'] = 1003 response['data'] = '未知错误' return response def show(): return 8
import os class ExistsError(Exception): pass class KeyInvalidError(Exception): pass def new_func(path,prev): """ 去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。 1000,成功 1001,文件不存在 1002,关键字为空 1003,未知错误 ... :return: """ response = {'code':1000,'data':None} try: if not os.path.exists(path): raise ExistsError() if not prev: raise KeyInvalidError() pass except ExistsError as e: response['code'] = 1001 response['data'] = '文件不存在' except KeyInvalidError as e: response['code'] = 1002 response['data'] = '关键字为空' except Exception as e: response['code'] = 1003 response['data'] = '未知错误' return response
三 . 加密
import hashlib def md5(pwd): # 实例化对象 obj = hashlib.md5() # 写入要加密的字节 obj.update(pwd.encode('utf-8')) # 获取密文 return obj.hexdigest() user = input("请输入用户名:") pwd = input("请输入密码:") if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a': print('登录成功') else: print('登录失败')
以上加密算法虽然厉害,但是存在缺陷,可以通过撞库进行反解 . 所以 , 有必要对加密算法中添加Salt再来加密 .
import hashlib SALT = b'2erer3asdfwerxdf34sdfsdfs90' def md5(pwd): # 实例化对象 obj = hashlib.md5(SALT) # 写入要加密的字节 obj.update(pwd.encode('utf-8')) # 获取密文 return obj.hexdigest() user = input("请输入用户名:") pwd = input("请输入密码:") if user == 'oldboy' and md5(pwd) == 'c5395258d82599e5f1bec3be1e4dea4a': print('登录成功') else: print('登录失败')
四 . 日志
1. 单文件操作
import logging logger = 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') # 10 logging.info('x2') # 20 logging.warning('x3') # 30 logging.error('x4') # 40 logging.critical('x5') # 50 logging.log(10,'x6')
import logging import traceback logger = 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) def func(): try: a = a +1 except Exception as e: # 获取当前错误的堆栈信息 msg = traceback.format_exc() logging.error(msg) func() # 在当前目录下创建一个XXXXXXX的文件,文件中内容为 : 2018-08-31 16:41:23 - root - ERROR -10.日志: Traceback (most recent call last): File "C:/Users/Administrator/PycharmProjects/untitled1/课件/day26/10.日志.py", line 22, in func a = a +1 UnboundLocalError: local variable 'a' referenced before assignment
这种方法可以方便我们更快速的找到错误的地方.
2. 自定义文件操作
import logging # 定义文件 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')
import logging # 定义文件 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 写日志时 , 会将相应的内容写入 li_1.log 和 li_2.log 文件中
-- 当使用 logger2 写日志时 , 会将相应的内容写入 l2_1.log 文件中