一,内置方法的进阶
1,__new__:在init之前,实例化对象的第一步是__new__创建了一个空间
如果没有类内没有定义__new__方法,默认执行object.__new__()
class Foo: def __init__(self): #初始化方法 print('执行了init') def __new__(cls, *args, **kwargs): #构造方法 print('执行了new') return object.__new__(cls) object = Foo()
应用:设计模式中的单例模式:
#单例模式 #一个类,只有一个实例的时候,单例模式 class Foo: __instance = None def __init__(self,name,age): #初始化方法 self.name = name self.age = age self.lst = [name] def __new__(cls, *args, **kwargs): #构造方法 if cls.__instance is None: cls.__instance = object.__new__(cls) return cls.__instance obj1 = Foo('alex',20) obj2 = Foo('egon',22) print(obj1.lst,obj2.lst)
2.__del__:析构方法:在删除这个类创建的对象的时候会先触发这个方法,再删除对象
做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
class Foo: def __init__(self,name,age): self.name = name self.age = age self.file = open('file',encoding='utf-8') def write(self): print(self.file.read()) def __del__(self): #析构方法 self.file.close() print('执行del了') f = Foo('alex',20) f.write() print(f)
del f #执行释放系统资源,程序结束也会自动执行
3.__len__:在类中实现了__len__方法,才能使用len()
能使用len()的常见数据类型有:list,dict,set,str
class Class: def __init__(self,name,course): self.name = name self.course = course self.students = [] def __len__(self): return len(self.students) s1 = Class('1班','数据结构') s1.students.append('wangxiaoming') s1.students.append('zhangsan') s1.students.append('lisi') print(len(s1)) #定义了__len__,对象可以直接使用len()
4.__eq__:在类中实现了__eq__方法,在执行==操作时自动调用
class Staff: def __init__(self,name,sex): self.name = name self.sex = sex def __eq__(self, other): return self.__dict__ == other.__dict__ obj = Staff('alex','不详') obj2 = Staff('alex','不详') obj3 = Staff('alex2','female') print(obj == obj2) #obj.__eq__(obj2) print(obj2 == obj3)
5.__hash__:哈希算法
1.对于相同的值在一次程序的运行中,总是不变的
2.对于不同的值在一次程序的运行中,总是不一样的
Q1:字典为什么寻址快,字典在内存中是如何存储的,为什么字典的key必须可哈希
在加载字典时,字典的键转换为哈希值,并把键的值存入哈希值对应的内存地址,字典在寻址的时候,直接根据需要查询的键的哈希值,直接寻找到对应的内存空间
Q2:set的去重机制(不能通过逐个判断值相等这件事来做去重工作,hash算法也不是完全的靠谱)
1.对每一个元素进行hash计算出一个内存地址
2.到这个内存地址上查看
如果这块内存中没有值
将这个元素存到对应的内存地址上
如果这块内存中已经有值
判断这两个值是否相等
如果相等就舍弃后面的值
如果不相等 就二次寻址再找一个新的空间来存储这个值
class Staff: def __init__(self,name,age,sex,dep): self.name = name self.age = age self.sex = sex self.dep = dep def __hash__(self): return hash(self.name + self.sex) def __eq__(self, other): if self.name == other.name and self.sex == other.sex: return True name_lst = ['yuan','egon','nazha','peiqi'] obj_lst = [] for i in range(100): name = name_lst[i%4] obj = Staff(name,i,'male','python') obj_lst.append(obj) print(obj_lst) ret = set(obj_lst) print(ret) for i in ret: print(i.name,i.age)