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())

  

 

posted @ 2019-07-02 14:03  zheng1076  阅读(207)  评论(0编辑  收藏  举报