python学习之老男孩python全栈第九期_day028知识点总结——面向对象进阶、hashlib
一. 面向对象进阶与实例
dic = {'k': 'v' } 对象:存储 属性 和 调用方法 dic['k'] = 'v' class Foo: def __init__(self, name, age, sex): self.name = name self.age = age self.sex = sex def __getitem__(self, item): if hasattr(self, item): return self.__dict__[item] def __setitem__(self, key, value): self.__dict__[key] = value def __delitem__(self, key): del self.__dict__[key] f = Foo('egon', 22, '男') print(f['a']) print(f['name']) f['hobby'] = '男' print(f.hobby,f['hobby']) print(f.__dict__) del f.hobby # object 原生支持 __delattr__ print(f.__dict__) print(f.__dict__) del f['hobby'] # 通过自己实现 print(f.__dict__)
__init__ :初始化方法 构造方法:创建一个对象 class A: def __init__(self): self.x = 1 print('in init function') def __new__(cls, *args, **kwargs): print('in new function') return object.__new__(A, *args, **kwargs) a = A() print(a.x)
设计模式:23 种 1. 单例模式:一个类始终只有一个实例 当第一次实例化这个类的时候,就创建一个实例化的对象 当之后再来实例化的时候,就用之前创建的那个对象 class A: __instance = False def __init__(self, name, age): self.name = name self.age = age def __new__(cls, *args, **kwargs): if cls.__instance: return cls.__instance else: cls.__instance = object.__new__(A) return cls.__instance egon = A('egon',22) egon.cloth = '小花袄' nezha = A('nezha',32) print(nezha) print(egon) # 内存地址一样 print(nezha.name) # nezha print(egon.name) # nezha print(nezha.cloth) # 小花袄
__eq__ class A: def __init__(self, name): self.name = name def __eq__(self,other): if self.name == other.name: return True else: return False obj1 = A('egon') obj2 = A('egn') print(obj1 == obj2) # 不实现__eq__时,默认比较内存地址 Flase
# __hash__ hash() class A: def __init__(self,name,sex): self.name = name self.sex = sex def __hash__(self): return hash(self.name+self.sex) a = A('egon','男') b = A('egon','男') print(hash(a)) print(hash(b)) a = A('egon','男') b = A('egn','男') print(hash(a)) print(hash(b))
实例
1 import json 2 from collections import namedtuple 3 Card = namedtuple('Card',['rank','suit']) # rank 牌的大小,suit 牌的花色 4 # c1 = Card(2,'红桃') 5 # print(c1) 6 # print(c1.suit) 7 class FranchDeck: 8 ranks = [str(n) for n in range(2,11)] + list('JQKA') # 2 - A 9 suits = ['红桃', '方块', '梅花', '黑桃'] 10 11 def __init__(self): 12 self.__cards = [Card(rank, suit) for rank in FranchDeck.ranks 13 for suit in FranchDeck.suits] 14 def __len__(self): 15 return len(self.__cards) 16 def __getitem__(self, item): 17 return self.__cards[item] 18 def __setitem__(self, key, value): 19 self.__cards[key] = value 20 def __str__(self): 21 return json.dumps(self.__cards, ensure_ascii=False) 22 deck = FranchDeck() 23 print(deck[10]) 24 from random import choice 25 print(choice(deck)) 26 from random import shuffle 27 shuffle(deck) 28 print(deck[10]) 29 print(deck) 30 print(deck[:4])
# 内置函数 内置的模块 内置的基础类型 ,都和类的内置方法有联系
# 一道面试题:有一个类,这个类有100个对象,其中有很多对象,名字和性别相同,但年龄不同,就认为是同一个对象,实现去重 class A: def __init__(self, name, sex, age): self.name = name self.sex = sex self.age = age def __eq__(self, other): return self.name == other.name and self.sex == other.sex def __hash__(self): return hash(self.name + self.sex) a = A('egon', '男',22) b = A('egon', '男',23) print(set((a,b))) # set 依赖对象的 hash eq
二. hashlib
非常非常重要 非常非常重要 非常非常重要 登录认证 摘要算法 import hashlib # 提供摘要算法的模块 md5 = hashlib.md5() md5.update(b'alex3714') print(md5.hexdigest()) # 结果不会变 不管算法多么不同,摘要的功能始终不变 对于相同的字符串使用同一个算法进行摘要,得到的值总是不变的 使用不同算法对相同的字符串进行摘要,得到的值应该不同 不管使用什么算法,hashlib的方式永远不变 import hashlib paw = hashlib.sha1() paw.update(b'alex3714') print(paw.hexdigest()) sha 算法, 随着算法复杂程度的增加, 摘要的时间成本 空间成本都会增加 摘要算法 密码的密文存储 文件的一致性验证 在下载时,会检查下载的文件和远程服务器上的文件是否一致 两台机器上的两个文件,想检查这两个文件是否相等 用户注册 用户输入用户名 用户输入密码 确认密码 明文的密码进行摘要,拿到一个密文的密码写到文件里 用户登录 import hashlib user = input('请输入用户名:') password = input('请输入密码:') with open('userInfo',encoding='utf-8') as f: for line in f: user,passwd,job = line.split('|') md5 = hashlib.md5() md5.update(bytes(password,encoding='utf-8')) md5_password = md5.hexdigest() if user == user and md5_password == passwd: print('登录成功') 撞库 加盐 import hashlib md5 = hashlib.md5(bytes('salt',encoding='utf-8')) md5 = hashlib.md5() md5.update(b'123456') print(md5.hexdigest()) 动态加盐 用户名 密码 使用用户名的一部分作为盐 import hashlib md5 = hashlib.md5(bytes('salt',encoding='utf-8') + b'135') md5.update(b'123456') print(md5.hexdigest()) 摘要算法:做摘要计算的,把字节类型的内容进行摘要处理 md5 sha1 md5加密方式 正常的md5算法、加盐的、动态加盐 文件的一致性校验 文件的一致性校验这里不需要加盐 import hashlib md5 = hashlib.md5() md5.update(b'alex') md5.update(b'3714') # md5.update(b'alex3714') 一样的 print(md5.hexdigest())