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

  

原文地址:https://www.cnblogs.com/gyh412724/p/9410474.html