主要内容:
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规范 # 所有的模块导入都应该尽量放在这个文件的开头 # 模块的导入也是有顺序的 # 先导入内置模块 # 再导入第三方模块 # 最后导入自定义模块