Python学习笔记28:面向对象进阶及 hashlib
__new__
# 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 # cls.__instance = object.__new__(cls) # return cls.__instance # # # egon = A('egg',38) # egon.cloth = '小花袄' # nezha = A('nazha',25) # print(nezha) # print(egon) # print(nezha.name) # print(egon.name) # print(nezha.cloth)
__eq__
# __eq__ # class A: # def __init__(self,name): # self.name = name # # def __eq__(self, other): # 正常情况是比较内存地址,但是可以自定义比较内容,通过__eq__ # if self.name == other.name: # return True # else: # return False # # ob1 = A('egg') # ob2 = A('egg') # print(ob1 == ob2) # 默认比较内存地址 # print(ob1 is ob2)
__hash__
# __hash__ # hash() 只要可hash的,里面肯定实现了一个__hash__方法 # class A: # def __init__(self,name,sex): # self.name = name # self.sex = sex # # def __hash__(self): # 只要定义了hash函数,就用自己的,从而改变了hash函数的默认比较方式 # return hash(self.name+self.sex) # # ob1 = A('egg','男') # ob2 = A('egg','男') # print(hash(ob1)) # print(hash(ob2)) # 默认是依据内存地址进行hash的
# 面试题 # 100 名字 和 性别 年龄不同 # set 去重 # class A: # def __init__(self,name,sex,age): # self.name = name # self.sex = sex # self.age = age # # # def __eq__(self, other): # if self.name == other.name and self.sex == other.sex: # return True # return False # # # def __hash__(self): # return hash(self.name + self.sex) # # a = A('egg','男',38) # b = A('egg','男',37) # print(set((a,b))) # unhashable # set 依赖对象的 hash eq
# 纸牌游戏
# import json # from collections import namedtuple # Card = namedtuple('Card',['rank','suit']) # rank 牌面的大小 suit牌面的花色 # c1 = Card(2,'红心') # print(c1) # class FranchDeck: # ranks = [str(n) for n in range(2,11)] + list('JQKA') # 2-A # suits = ['红心','方板','梅花','黑桃'] # # def __init__(self): # self._cards = [Card(rank,suit) for rank in FranchDeck.ranks # for suit in FranchDeck.suits] # for suit in FranchDeck.suits: # for rank in FranchDeck.ranks: # Card(rank, suit) # def __len__(self): # return len(self._cards) # # def __getitem__(self, item): # return self._cards[item] # # def __setitem__(self, key, value): # self._cards[key] = value # # def __str__(self): # return json.dumps(self._cards,ensure_ascii=False) # 这里需要进行序列化 # deck = FranchDeck() # print(deck[10]) from random import choice # 这里会依赖内置的len方法,所以这里只能实现一个__len__方法 # print(choice(deck)) # print(choice(deck)) # from random import shuffle # 还依赖与setitems方法,打乱顺序 # shuffle(deck) # print(deck[10]) # print(deck) # print(deck[:5])
hashlib
# 摘要算法,解释hashlib算法,只要有一个字符不同,结果不一样就不一样 # 两个字符串 : # import hashlib # 提供摘要算法的模块,里面有一堆算法,md5,sha系列算法 # md5 = hashlib.md5() # md5.update(b'123456') # 这里必须钥匙一个bytes类型的数据 # print(md5.hexdigest()) # 要调用hexdigest()获取结果 #aee949757a2e698417463d47acac93df # 不管算法多么不同,摘要的功能始终不变 # 对于相同的字符串使用同一个算法进行摘要,得到的值总是不变的 # 使用不同算法对相同的字符串进行摘要,得到的值应该不同 # 不管使用什么算法,hashlib的方式永远不变 # import hashlib # 提供摘要算法的模块 # sha = hashlib.md5() # sha.update(b'alex3714') # print(sha.hexdigest()) # sha 算法 随着 算法复杂程度的增加 我摘要的时间成本、空间成本都会增加 # 摘要算法-只能加密,不能解密 # 密码的密文存储 # 文件的一致性验证 # 在下载的时候 检查我们下载的文件和远程服务器上的文件是否一致 # 两台机器上的两个文件 你想检查这两个文件是否相等
# 加盐,为了不被轻易撞库破解,进行加盐
# import hashlib # 提供摘要算法的模块
# md5 = hashlib.md5(bytes('盐',encoding='utf-8'))
# # md5 = hashlib.md5()
# md5.update(b'123456')
# print(md5.hexdigest())
# 动态加盐
# 用户名 密码
# 使用用户名的一部分或者 直接使用整个用户名作为盐
# import hashlib # 提供摘要算法的模块
# md5 = hashlib.md5(bytes('盐',encoding='utf-8')+b'123') # 这里加b'需要加的东西'
# # md5 = hashlib.md5()
# md5.update(b'123456')
# print(md5.hexdigest())
# 文件的一致性校验
# 文件的一致性校验这里不需要加盐,文件非常长的时候可以分次进行加密,切分次进行加密最后的结果和一次加密的结果是一样的
# import hashlib
# md5 = hashlib.md5()
# md5.update(b'alex')
# md5.update(b'3714')
# print(md5.hexdigest())