1,__getitem__、__setitem__、__delitem__方法
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',38,'男') print(f['name']) f['hobby'] = '男' print(f.hobby,f['hobby']) # del f.hobby # object 原生支持 __delattr__ del f['hobby'] # 通过自己实现的 print(f.__dict__)
2,
# __init__ 初始化方法
# __new__ 构造方法 : 创建一个对象
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) a1 = A() a2 = A() a3 = A() print(a1) print(a2) print(a3) print(a1.x)
D:\python\mypy\venv\Scripts\python.exe D:/python/mypy/day28/类进阶.py
in new function
in init function
先执行__new__方法,再执行__init__方法。__new__的结果,return到__init__的输入
3,
# 设计模式
# 23种
# 单例模式
# 一个类 始终 只有 一个 实例
# 当你第一次实例化这个类的时候 就创建一个实例化的对象
# 当你之后再来实例化的时候 就用之前创建的对象
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)
4,__eq__方法
默认2个对象,只比较内存地址,加上__eq__方法后,按__eq__方法的定义进行比较
class A: def __init__(self,name): self.name = name def __eq__(self, other): if self.__dict__ == other.__dict__: return True else: return False ob1 = A('egon') ob2 = A('egg') print(ob1 == ob2)
5,
import json from collections import namedtuple Card = namedtuple('Card',['rank','suit']) # rank 牌面的大小 suit牌面的花色 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] 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]) #需要__getitem__支持 from random import choice print(choice(deck)) #需要__len__支持 # print(choice(deck)) from random import shuffle shuffle(deck) #需要调用__setitem__ print(deck[10]) print(deck) #需要调用__str__,完成所有牌的输出 print(deck[:5])
# 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
6,
hash() #__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','nv') print(hash(a)) print(hash(b))
# 动态加盐 # 用户名 密码 # 使用用户名的一部分或者 直接使用整个用户名作为盐 import hashlib # 提供摘要算法的模块 md5 = hashlib.md5(bytes('盐',encoding='utf-8')+b'') # md5 = hashlib.md5() md5.update(b'123456') print(md5.hexdigest()) #import hashilib # 做摘要计算的 把字节类型的内容进行摘要处理 # md5 sha # md5 正常的md5算法 加盐的 动态加盐 # 文件的一致性校验 # 文件的一致性校验这里不需要加盐 import hashlib md5 = hashlib.md5() md5.update(b'alex') #对内容进行分批摘要,结果会是一样的。如一个文件分批摘要 md5.update(b'3714') print(md5.hexdigest())
作业:对一个文件进行摘要算法,最后计算出这个文件的md5值。
import hashlib file_path = r'D:\迅雷下载\小森林.冬春篇.BD1280超清日语中字.mp4' md5 = hashlib.md5() sha = hashlib.sha1() with open(file_path,mode='rb') as f: content = f.read(10240000) # 按10MB分批算 while content: md5.update(content) sha.update(content) content = f.read(10240000) print('md5:',md5.hexdigest()) print('sha1:',sha.hexdigest())View Code