1、析构方法:释放一个空间之前执行 (new构造方法 申请一个空间)
某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源 网络资源
1)垃圾回收机制
class A:
def __del__(self):
# 析构方法 del A的对象 会自动触发这个方法
print('执行我了')
a = A()
del a # 对象的删除 del
print(a)
此时执行结果异常
更改后(将del a这一行注释掉)
class A:
def __del__(self):
# 析构方法 del A的对象 会自动触发这个方法
print('执行我了')
a = A()
#del a # 对象的删除 del
print(a)
此时执行结果正常
以上例子就是将我们定义的变量手动清理,上面因为清理了所以后面打印就会报错,下面的例子则正常执行
2) 不管是主动还是被动,下面的f对象总会被清理掉,被清理掉就触发__del__方法,触发这个方法就会归还操作系统的文件资源
class File():
# 处理文件的
def __init__(self,file_path):
self.f = open(file_path)
self.name = 'alex'
def read(self):
self.f.read(1024)
def __del__(self): # 是去归还/释放一些在创建对象的时候借用的一些资源
# del 对象的时候 程序员触发
# python解释器的垃圾回收机制 回收这个对象所占得内存的时候 python自动触发的
self.f.close()
f = File('liuys.txt')
f.read()
注:申请一块儿空间是操作系统分配,以及在这一块儿空间之内的所有事儿都归的python解释器来管理
3)操作流程:# python --> 操作系统 --> 文件操作符 --> 硬盘里的文件
f = open('wenjian')
f.close()
关闭python解释器的内存
del f
2、item系列(和对象使用[]访问值有联系)
例如:
obj = {'k':'v'}
print(obj) # 字典的对象
print(obj['k'])
在内置的模块中,有一些特殊的方法,要求对象必须实现__getitem__/__setitem__才能使用
例如:
字典模型
class B:
def __getitem__(self, item):
return getattr(self,item)
def __setitem__(self, key, value):
setattr(self,key,value*2)
def __delitem__(self, key):
delattr(self,key)
b = B()
# b.k2 = 'v2'
# print(b.k2)
b['k1'] = 'v1' # __setitem__
print(b['k1']) # __getitem__
del b['k1'] # __delitem__
print(b['k1'])
列表模型
class B:
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)
b = B(['111','222','ccc','ddd'])
print(b.lst[0])
print(b[0])
b[3] = 'alex'
print(b.lst)
del b[2]
print(b.lst)
3、hash方法
底层数据结构基于hash值寻址的优化操作
hash是一个算法
能够把某一个要存在内存里的值通过一系列计算,
保证不同值的hash结果是不一样的
'127647862861596' ==> 927189778748
对同一个值在多次执行python代码的时候hash值是不同
但是对同一个值 在同一次执行python代码的时候hash值永远不变
所有的hash之不会变
print(hash('abc')) # 6048279107854451739
print(hash('abc'))
print(hash('abc'))
print(hash('abc'))
print(hash('abc'))
print(hash('abc'))
字典的寻址 - hash算法
d = {'key':'value'}
hash - 内置函数
set集合
se = {1,2,2,3,4,5,'a','b','d','f'}
print(se)
d = {'key':'v1','key':'v2'}
print(d['key'])
hash(obj) #obj内部必须实现了__hash__方法
4、eq方法(判断两字段的值是相同,一般可以用在hash算法后两个不同值hash值却相同的判断)
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('alex',83)
aa = A('alex',83)
aa2 = A('alex',83)
aa3 = A('alex',83)
aa4 = A('alex',83)
aa5 = A('alex',83)
aa6 = A('alex',83)
print(a,aa)
print(aa3 == aa == aa4) # ==这个语法 是完全和__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值相等的时候才会触发
采用的是将姓名和性别进行hash处理,在通过eq计算判断hash值相同的不同值
执行结果:
结果将2000个相同的用户信息全部去重了