一、昨日内容回顾
1.钻石继承
#新式类,本身或父类显示继承object
#找名字的时候是广度优先顺序
#有mro方法,super方法,
# super并不是单纯的找父类,和mro顺序是完全对应的
# super class A: def func(self): print('A') class B(A): def func(self): print('B') super().func() class C(A): def func(self): print('C') super().func() class D(B,C): def func(self): print('D') super().func() # D().func() D.mro() # B().func() # print(B.mro()) # super并不是单纯的找父类,和mro顺序是完全对应的
#python3中全部是新式类,默认继承object
#经典类,不显式继承object类
#python2独有
#找名字的时候是深度优先
#没有mro和super方法。
2.多态
#python自带多态
#Java需要通过继承实现
3.封装
#私有的概念 __名字
私有的对象属性
私有的静态属性
私有的方法
#不能从外部调用,不能子类继承,在类的内部使用时会自动变形:_类名__名字
4.几个装饰器
#@property 一个方法伪装成属性
#@f.setter 修改一个属性的使用调用这个方法
#@f.deleter 删除一个伪装成方法的属性的使用用这个方法
#@classmethod 绑定类方法
类方法
调用者是类
默认参数是CLS,表示当前类。
主要用途,用来操作类的静态变量,类方法,静态方法
#@staticmethod 静态方法
调用者是类
没有默认参数
# 什么时候用静态方法
# 既不会用到对象的资源也不会用到类的资源的时候
二、常用模块
1、hashlib
1、hash算法简介
1)、hash()的讲解
#把一个数据转换成一个数字的算法
#在同一次执行的过程中,对同一个可hash的值进行多次计算得出的结果总是相同的。
2)、有什么用?有什么特点?
在数据的存储方面提供优化。
字典-通过键快速找到值:
集合-去重
#为什么对同一个值计算hash值每次运行结果都不同?
由于每一次执行程序所获得存储空间都不一定相同,所以多次执行统一代码得到的hash值可能不同。
2.hashlib
hashlib的特点
#是一个模块,提供多种算法md5,sha1.....
#同一个字符串用同一种算法进行加密,结果总是相同的
#同一个字符串用不同算法进行加密,结果总是不同的
1)应用1:注册登录
(1)md5—— 暴力破解,撞库
# sha算法 —— 是一个算法集,
# 随着后面的数字越大,计算的时间越长,结果越长,越安全
# md5 登录认证 # 简单登录--暴力破解、撞库 # username = input("username>>>").strip() # password = input("password>>>").strip() # md5_obj = hashlib.md5() # md5_obj.update(password.encode('utf-8')) # md5_str = md5_obj.hexdigest() # print(md5_str) # with open('userinfo', 'r', encoding='utf-8') as f: # for line in f: # name, pd = line.strip().split('|') # if name == username and pd == md5_str: # print('登录成功!') # break
(2)加盐——恶意注册
# 加盐的摘要算法--恶意注册 # username = input("username>>>").strip() # password = input("password>>>").strip() # md5_obj = hashlib.md5('盐'.encode('utf-8')) # md5_obj.update(password.encode('utf-8')) # md5_str = md5_obj.hexdigest() # print(md5_str) # with open('userinfo', 'r', encoding='utf-8') as f: # for line in f: # name, pd = line.strip().split('|') # if name == username and pd == md5_str: # print('登录成功!') # break
(3)动态加盐———每一个用户的密码的密文的盐都不一样
# 动态加盐的摘要算法--完美 username = input("username>>>").strip() password = input("password>>>").strip() md5_obj = hashlib.md5(username.encode('utf-8')) md5_obj.update(password.encode('utf-8')) md5_str = md5_obj.hexdigest() print(md5_str) with open('userinfo', 'r', encoding='utf-8') as f: for line in f: name, pd = line.strip().split('|') if name == username and pd == md5_str: print('登录成功!') break
2)应用2:检验文件的一致性:md5 速度快
(1)小文件
(2)大文件
# md5验证文件的一致性 # 大文件 import os with open(r'D:\Python\Projects\py笔记\day19\02-燃烧基础知识.mp4', mode='rb') as f: md5_obj = hashlib.md5() filesize = os.path.getsize(r'D:\Python\Projects\py笔记\day19\02-燃烧基础知识.mp4') while filesize > 0: md5_obj.update(f.read(1024)) filesize = filesize - 1024 md5_str = md5_obj.hexdigest() print(md5_str) #1b83b992bce178702e57ce3e623f98f7
hashlib小结:
摘要算法,md5、sha1算法
2、configparse
import configparser # config = configparser.ConfigParser() # config["DEFAULT"] = {'ServerAliveInterval': '45', # 'Compression': 'yes', # 'CompressionLevel': '9', # 'ForwardX11':'yes' # } # config['bitbucket.org'] = {'User':'hg'} # config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} # with open('example.ini', 'w') as f: # config.write(f) import configparser config = configparser.ConfigParser() # print(config.sections()) # [] config.read('example.ini') # print(config.sections()) # ['bitbucket.org', 'topsecret.server.com'] # print('bytebong.com' in config) # False # print('bitbucket.org' in config) # True # print(config['bitbucket.org']["user"]) # hg # print(config['DEFAULT']['Compression']) #yes # print(config['topsecret.server.com']['ForwardX11']) #no # print(config['bitbucket.org']) #<Section: bitbucket.org> # for key in config['bitbucket.org']: # 注意,有default会默认default的键 # print(key) # print(config.options('bitbucket.org')) # 同for循环,找到'bitbucket.org'下所有键 # print(config.items('bitbucket.org')) #找到'bitbucket.org'下所有键值对 # print(config.get('bitbucket.org','compression')) # yes get方法Section下的key对应的value
3、logging
1) 为什么要写日志的模块
#代码遇到问题的时候--写给程序员看
一些中间结果起到的排错作用,需要打印出来 -- 在排错的过程中
在真正提供服务的时候 -- 不需要
#记录用户的行为---写给用户看
---写给公司看
2)为什么要用logging模块
#格式规范
#帮你把日志的紧急情况进行分类
3)logging的基础配置basicConfig
# logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(filename)s[line: %(lineno)d] %(levelname)s %(message)s', # #datefmt = '%a, %d %b %Y %H:%M:%S', # filename='log', # filemode='w') # # logging.debug('debug message') # logging.info('info message') # logging.warning('warning message') # logging.error('error message') # logging.critical('critical message')
4)使用logger的对象的形式进行配置
logger = logging.getLogger() fmt = logging.Formatter('%(asctime)s-%(filename)s-%(name)s-%(levelname)s-%(message)s') fh = logging.FileHandler('logger_file', encoding='utf-8') fh.setFormatter(fmt) fmt2 = logging.Formatter('%(asctime)s-%(name)s-%(levelname)s-%(message)s') sh = logging.StreamHandler() sh.setFormatter(fmt2) sh.setLevel(level=logging.DEBUG) logger.setLevel(level=logging.WARNING) logger.addHandler(fh) logger.addHandler(sh) logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')