23 析构方法 items系列 hash方法 eq方法
主要内容:
1. 析构方法 __del__
析构方法 : 释放一个空间之前执行 (构造方法: 申请一个空间)
垃圾回收机制
class A:
def __del__(self):
# 析构方法 del A的对象 会自动触发这个方法
print('执行我了',self)
a = A()
del a # 对象的删除 del #先执行__del_,然后删除a
print(a) #这个时候再打印a会出现错误.
python解释器内部做的事情:
a : 申请一块空间,操作系统分配给你的
b : 在这一块空间之内的所有事,归你的python解释器来管理.
如果某对象借用了操作系统的资源,还要通过析构方法归还回去 : 文件资源 , 网络资源 .
#处理文件的
class File:
def __init__(self,file_path):
self.f = open(file_path)
def read(self):
self.f.read(124)
def __del__(self): #是去归还/释放一些在创建对象的时候借用的一些资源
#del 对象的时候 程序员触发
#python解释器的垃圾回收机制 回收这个对象所占内存的时候 python自动触发.
self.f.close()
f = File('123456')
f.read()
# 不管是主动还是被动,这个f对象总会被清理掉,被清理掉就触发__del方法,触发这个方法就会归还操作系统的文件资源.
2. items系列 包含 :__getitem__/__setitem__/__delitem
irems系列和方括号有关系.
class A:
def __getitem__(self, item):
return getattr(self,item) #反射中的获取属性
def __setitem__(self, key, value):
setattr(self,key,value) #反射中的设置属性 #self.k1 = v1
def __delitem__(self, key):
delattr(self,key)
a = A()
a['k1'] = 'v1' #执行__setitem__方法
print(a['k1']) #执行__getitem__方法
del a['k1'] #执行__delitem__方法
print(a['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 #反射中的设置属性 #self.k1 = v1
def __delitem__(self, key):
self.lst.pop(key)
a = A([11,22,3,44,55,66])
print(a.lst[0])
print(a[0])
a[1] = 10
print(a[1])
print(a.__dict__) #{'lst': [11, 10, 3, 44, 55, 66]}
a.lst.pop(1)
print(a.__dict__) #{'lst': [11, 3, 44, 55, 66]}
3 . hash 方法 : 底层数据结构基于hash值寻址的优化操作
hash是一个算法,能够把某一个要存在内存的值通过一系列运算,保证不同的值hash结果是不一样的.
对于同一个值在, 在同一次执行python代码的时候hash值永远不变
对于同一个值,在多次执行python代码的时候,hash值是不同的.
print(hash('12344ff'))
print(hash('12344ff'))
print(hash('12344ff'))
print(hash('12344ff'))
# 第一次执行的结果: -5787132279899563087,-5787132279899563087, -5787132279899563087,-5787132279899563087
# 第二次执行的结果: 8543566635004474721, 8543566635004474721, 8543566635004474721, 8543566635004474721
# 注意 : 同一次执行的时候,值是相同的,多次执行值就不同
a : 字典的寻址
d = {'key':'v1','key1':'v2'}
print(d['key'])
寻址的方式: 1) 计算key的hash值,
2) 在内存中找到该haash值所对应的value.
b : set集合的去重
set = {1,2,2,3,5,'a','b','wert2234','yuiop5654'}
# 1. 先计算1所对的hash值,在计算b所对的hash值,依次计算
# 2. 如果hash值相等,判断这两个值是否相等
# 3. 如果相等,去重覆盖,如果不等,则二次寻址.
去重的方式: 1)先计算每一项的hash值
2) 如果hash值相同,在判断两个值是否相同.
3) 如果相同,去重覆盖,如果不同,则二次寻址.
4. __eq__内置方法 : == 自动触发执行 __eq方法
class A:
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
def __eq__(self, other):
if self.name == other.name and self.age == other.age and self.sex == other.sex:
return True
a = A('alex', '29', 'male')
a1 = A('alex', '29', 'male')
a2 = A('alex', '28', 'male')
a3 = A('alex', '29', 'male')
# a.func(a1)
print(a == a1) # == 自动触发__eq__方法
5 . 一道面试题
一个类 员工管理系统
对象的属性 : 姓名 性别 年龄 部门
内部转岗 python开发 - go开发
姓名 性别 年龄 新的部门
alex None 83 python
alex None 85 luffy
1000个员工 如果几个员工对象的姓名和性别相同,这是一个人请对这1000个员工做去重
class Emplyee:
def __init__(self, name, age, sex, department):
self.name = name
self.age = age
self.sex = sex
self.department = department
def __hash__(self): #判断姓名和性别所对应的hash值,如果不同就直接加到列表中,如果相同则判断值(__eq__)
return hash('%s%s' % (self.name,self.sex))
def __eq__(self, other):
if self.name == other.name and self.sex == other.sex: #判断值是否等,如相等,则执行_hash_去重覆盖,不等就二次寻址.
return True
employee_list = []
# 实例化1000个员工
for i in range(200):
employee_list.append(Emplyee('alex', i, 'male', 'python'))
for i in range(200):
employee_list.append(Emplyee('wusir', i, 'male', 'python'))
for i in range(200):
employee_list.append(Emplyee('sylar', i, 'male', 'python'))
employee_list = set(employee_list)
for person in employee_list:
print(person.__dict__)
6. 模块
a: 模块的分类:内置模块 :
安装python解释器的时候跟着装上的方法
第三方模块/扩展模块 : 没有安装python解释器的时候安装的那些功能
自定义模块 :你写的功能如果是一个通用的功能,那就把他当成一个模块.
b: 什么是模块 : 有的功能开发者自己无法完成,这样的话需要借助已经实现的函数/类来完成这些功能.
你实现不了的功能别人替你实现了:
操作系统打交道; 和时间 ; 1000取随机数 ; 压缩一个文件; 和网络通信.
别人写好的一组功能 : 文件夹/ py文件 / c语言编译好的一些编译文件
c: 为什么使用模块
分类管理方法 ; 节省内存 ; 提供更多的功能
d: 模块的创建和导入:
import my_module
#my_module.py文件的内容
'''
name = 'alex'
def login():
print('login', name)
name = 'sylar'
'''
my_module.login()
# import这个语句相当于执行了什么?
# import这个模块相当于执行了这个模块所在的py文件
(1)import 这个语句的执行流程:
1)找到my_module这个文件
2)创建一个属于my_module的空间
3)从上到下执行module
4)将这个模块所在的命名空间建立一个和my_module之间的一个引用.
(2)一个模块可以被重复导入吗? : 一个模块不会被重复导入
(3)模块的重命名 : import my_module as m
(4)导入多个模块:
import os
import my_module
# PEP8规范
# 所有的模块导入都应该尽量放在这个文件的开头
# 模块的导入也是有顺序的
# 先导入内置模块
# 再导入第三方模块
# 最后导入自定义模块

浙公网安备 33010602011771号