析构方法:_ _del_ _
释放一个空间之前执行.
注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
a=10 print(a) # 结果:10 a=10 del a print(a) # name 'a' is not defined
del A的对象会自动触发__del__方法
class A: def __del__(self): print("执行了....") a=A() del a print(a) 结果:执行了.... 报错:name 'a' is not defined 结论:先执行__del__再执行删除
# class A: # def __del__(self): # print("执行了....") # a=A() # print(a) # 结果:<__main__.A object at 0x0000022830835240> # 执行了.... # 结论:程序启动需要开辟一块空间,当程序结束的时候表面上结束,但是python解释器需要释放掉所有的内存空间
文件处理
# class File(): # # 处理文件 # def __init__(self,file_math): # self.f=open("file_math") # def read(self): # self.f.read(1024) # def __del__(self): # 是去归还/释放一些在创建对象的时候借用的一些资源 # # del 对象的时候执行__del__ 是程序员触发, # # python解释器的垃圾回收机制 回收这个对象所占得内存的时候执行__del__ 是python自动触发的, # self.f.close() # f=File("文件") # f.read() # 不管是主动还是被动,这个f对象总会被清理掉,被清理掉就触发__del__方法,触发这个方法就会归还操作系统的文件资源
item系列,和使用对象[]访问值有联系
obj={"k":"v"} print(obj) print(obj["k"]) 结果:{'k': 'v'} v class A: print("执行了...") a=A() print(a["b"]) 结果:报错:'A' object is not subscriptable class A: def __getitem__(self, item): print("执行了...",item) return "aaaaaa" a=A() print(a["b"]) print(a["k"]) 结果: 执行了... b aaaaaa 执行了... k aaaaaa class A: def __getitem__(self, item): print("执行了...",item) return "aaaaaa" def __setitem__(self, key, value): print(key,value) a=A() a["k"]="value" # 结果: k value print(a["k"]) #误区 结果是: # 执行了... k # aaaaaa
# 在内置的模块中,
# 有一些特殊的方法,要求对象必须实现__getitem__/__setitem__才能使用
class A: def __getitem__(self, item): return getattr(self,item) def __setitem__(self, key, value): setattr(self,key,value) a=A() a["k1"]="v1" print(a.k1) print(a["k1"]) 结果: v1 v1 class A: def __getitem__(self, item): return getattr(self,item) def __setitem__(self, key, value): setattr(self,key,value) def __delitem__(self, key): print(key) a=A() a["k1"]="v1" print(a["k1"]) del a["k1"] print(a["k1"]) 结果: v1 k1 v1 并没有删除 所以: class A: def __getitem__(self, item): return getattr(self,item) def __setitem__(self, key, value): setattr(self,key,value) def __delitem__(self, key): delattr(self,key) a=A() a["k1"]="v1" print(a["k1"]) del a["k1"] print(a["k1"]) 结果:报错'A' object has no attribute 'k1' class A: def __init__(self,lst): self.lst=lst def __getitem__(self, item): return self.lst[item] def __setitem__(self, key, value): self.lst[key]=value def __delitem__(self, key): self.lst.pop(key) a=A([111,222,333,444,555]) print(a.lst[0]) print(a[0]) a[3]=666 print(a.lst) del a[2] print(a.lst) 结果: 111 111 [111, 222, 333, 666, 555] [111, 222, 666, 555]
# 字典的寻址 hash算法
# 字典寻址要比列表快
# set集合寻址
# hash(obj) #obj内部必须实现了__hash__方法
hash方法
# 底层数据结构基于hash值寻址的优化操作
# hash是一个算法.
# 能够把某一个要存在内存里的值通过一系列计算,
# 保证不同值的hash结果是不一样的
# 对同一个值在多次执行python代码的时候hash值是不同
# 但是对同一个值 在同一次执行python代码的时候hash值永远不变
print(hash('abc')) print(hash('abc')) print(hash('abc')) print(hash('abc')) print(hash('abc')) print(hash('abc')) 注:一个run即为一次
eq方法
class A: pass a=A() a1=A() print(a,a1) print(a==a1) 实例化两个对象 结果: <__main__.A object at 0x0000025ED7D15240> <__main__.A object at 0x0000025ED7D15278> False
class A: def __init__(self,name,age): self.name=name self.age=age a=A("aaa",18) a1=A("aaa",18) print(a,a1) print(a==a1) 结果: <__main__.A object at 0x000001C2A5095F98> <__main__.A object at 0x000001C2A5095F60> False
class A: def __init__(self,name,age): self.name=name self.age=age def __eq__(self, other): if self.name==other.name and self.age==other.age: return True a=A("aaa",18) a1=A("aaa",18) a2=A("aaa",18) a3=A("aaa",18) a4=A("aaa",18) a5=A("aaa",18) print(a,a1) print(a==a1==a3)
结论:==这个语法 是完全和__eq__
一道面试题
# 一个类 # 对象的属性 : 姓名 性别 年龄 部门 # 员工管理系统 # 内部转岗 python开发 - go开发 # 姓名 性别 年龄 新的部门 # alex None 83 python # alex None 85 luffy # 1000个员工 # 如果几个员工对象的姓名和性别相同,这是一个人 # 请对这1000个员工做去重 # # class Employee: # def __init__(self,name,age,sex,partment): # self.name = name # self.age = age # self.sex = sex # self.partment = partment # def __hash__(self): # return hash('%s%s'%(self.name,self.sex)) # def __eq__(self, other): # if self.name == other.name and self.sex == other.sex: # return True # employ_lst = [] # for i in range(200): # employ_lst.append(Employee('alex',i,'male','python')) # for i in range(200): # employ_lst.append(Employee('wusir',i,'male','python')) # for i in range(200): # employ_lst.append(Employee('taibai', i, 'male', 'python')) # # # print(employ_lst) # employ_set = set(employ_lst) # for person in employ_set: # print(person.__dict__)
set集合的去重机制 : 先调用hash,再调用eq,eq不是每次都触发,只有hash值相等的时候才会触发