1、析构方法:释放一个空间之前执行 (new构造方法  申请一个空间)

                        某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源  网络资源

1)垃圾回收机制

class A:
    def __del__(self):
        # 析构方法 del A的对象 会自动触发这个方法
        print('执行我了')
a = A()
del a  # 对象的删除 del
print(a)

此时执行结果异常

python 构造 析构 self python的析构方法_寻址

更改后(将del a这一行注释掉)

class A:
    def __del__(self):
        # 析构方法 del A的对象 会自动触发这个方法
        print('执行我了')
a = A()
#del a  # 对象的删除 del
print(a)

此时执行结果正常

python 构造 析构 self python的析构方法_寻址_02

以上例子就是将我们定义的变量手动清理,上面因为清理了所以后面打印就会报错,下面的例子则正常执行

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值相同的不同值

执行结果:

python 构造 析构 self python的析构方法_bc_03

结果将2000个相同的用户信息全部去重了