zoukankan      html  css  js  c++  java
  • 《Python》内置方法进阶和常用模块

    一:__new__

       在__init__之前,实例化对象的第一步是__new__创建了一个空间

    class Foo:
        def __init__(self):             # 初始化方法
            print('执行了init')
        def __new__(cls, *args, **kwargs):  # 构造方法
            print('执行了new')
            return object.__new__(cls)
    obj = Foo()
    '''
    执行了new
    执行了init
    
    创造一个对象比喻成捏小人
    new是小人捏出来了
    init就是给小人穿衣服
    '''

       单例模式:

        一个类,只有一个实例的时候

    class Foo:
        __instance = None
        def __init__(self,name,age):    # 初始化方法
            self.name = name
            self.age = age
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None:
                cls.__instance = object.__new__(cls)
            return cls.__instance
    obj1 = Foo('alex',38)
    obj2 = Foo('taibai',28)
    print(obj1,obj2)    # <__main__.Foo object at 0x0132CE70> <__main__.Foo object at 0x0132CE70>
    print(obj1.name,obj2.name)  # taibai taibai
    '''
    单例模式的时候,不管实例化多少个对象,永远只取最后一个对象的值
    '''

    二、__del__

       析构方法,当对象在内存中被删除(释放)时,自动触发执行。

    class Foo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.file = open('file', mode='w')
        def write(self):
            self.file.write('sdfsdgsdgs')
        def __del__(self):  # 析构方法 : 在删除这个类创建的对象的时候会先触发这个方法,再删除对象
            # 做一些清理工作,比如说关闭文件,关闭网络的链接,数据库的链接
            self.file.close()
            print('执行del了')
    f = Foo('alex',38)
    del f
    print('hahahaha')
    '''
    执行del了
    hahahaha
    '''

    三、__len__

        __len__支持的数据类型跟函数len()是一样的:lst dict set tuple str

    # len()函数支持的数据类型---> lst dict set tuple str
    print('__len__' in dir(list))   # True
    print('__len__' in dir(dict))   # True
    print('__len__' in dir(set))    # True
    print('__len__' in dir(tuple))  # True
    print('__len__' in dir(str))    # True
    
    print('__len__' in dir(int))    # False
    print('__len__' in dir(float))  # False
    
    class Foo:
        def __len__(self):
            return 1
    obj = Foo()
    print(len(obj)) # 1
    
    class Class:
        def __init__(self,name,course):
            self.name = name
            self.course = course
            self.students = []
        def __len__(self):
            return len(self.students)
    s1 = Class('骑士1班','python')
    s1.students.append('laowang')
    s1.students.append('laoliu')
    s1.students.append('laocheng')
    print(len(s1))  # 3

    四、__eq__

       自定义两个实例化对象的值是否相等,是的话返回True

    class Staff:
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex
        def __eq__(self, other):
            return self.__dict__ == other.__dict__
    alex = Staff('alex','')
    alex1 = Staff('alex','')
    alex2 = Staff('alex','female')
    print(alex == alex1)    # True  两个对象的值相同
    print(alex2 == alex1)   # False 两个对象的值不同
    
    l1 = [1,2,3,4]
    l2 = [1,2,3,4]
    print(id(l1),id(l2))    # 1787304 1788464
    print(l1 == l2)     # True
    print(l1 is l2)     # False

    五、__hash__

        1、每次执行hash值都会变化

        2、在一次执行的过程中对同一个值的hash结果总是不变的

    class Foo():
        pass
    obj1 = Foo()
    obj2 = Foo()
    print(hash(obj1))   # 内存地址:319039
    
    print(hash(obj2))   # 内存地址:318993
    print(hash(obj2))   # 内存地址:318993
    print(hash(obj2))   # 内存地址:318993
    print(hash(obj2))   # 内存地址:318993
    print(hash(obj2))   # 内存地址:318993
    '''
    hash算法
    1、对于相同的值在一次程序的运行中是不会变化的
    2、对于不同的值在一次程序的运行中总是不同的
    '''
    # 不用set去重
    new_lst = []
    lst = [2,2,43,53,238579,14780]
    for i in lst:
        if i in new_lst:
            pass
        else:
            new_lst.append(i)
    
    set = {1,2,'abc',3,4,5,6,7,8,9,'bca'}
    # 不能通过逐个判断值相等这件事儿来做去重工作
    # hash算法也不是完全的靠谱
    # 
    # set 的去重机制
    #     1.对每一个元素进行hash计算出一个内存地址
    #     2.到这个内存地址上查看
    #         如果这块内存中没有值
    #             将这个元素存到对应的内存地址上
    #         如果这块内存中已经有值
    #             判断这两个值是否相等
    #                 如果相等 就舍弃后面的值
    #                 如果不相等 就二次寻址再找一个新的空间来存储这个值
    set的去重机制
    # 员工类
    # 姓名 年龄 性别 部门
    # 转岗位后
    # 姓名 年龄变化了 性别 部门变化了
    # 100个员工,去掉重复的
    # 员工的姓名 性别 是相同的,就认为是同一个员工
    
    class Staff:
        def __init__(self,name,age,sex,dep):
            self.name = name
            self.age = age
            self.sex = sex
            self.dep = dep
        def __hash__(self):
            return hash(self.name + self.sex)
        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:
                return True
    name_lst = ['alex','taibai','egon','peiqi']
    obj_lst = []
    for i in range(100):
        name = name_lst[i % 4]
        obj = Staff(name, i, 'male', 'python')
        obj_lst.append(obj)
    print(obj_lst)      # 打印出了100个对象的内存地址
    ret = set(obj_lst)
    print(ret)          # 去掉重复的,只剩4个了
    
    # 查看保留的值是保留前面的还是保留后面的
    for i in ret:       # 结果是保留前面的
        print(i.name,i.age)
    '''
    peiqi 3
    taibai 1
    egon 2
    alex 0
    '''
    面试题

    六、初识模块

       别人写好的功能放在一个文件里

         内置模块: 安装Python解释器的时候一起装上的

         第三方模块、扩展模块: 需要自己安装

         自定义模块: 自己写的py文件

       序列化模块:

         什么叫序列化:

           将原本的字典、列表等内容转换成一个字符串、byets类型的过程就叫做序列化。

    比如,我们在python代码中计算的一个数据需要给另外一段程序使用,那我们怎么给?
    现在我们能想到的方法就是存在文件里,然后另一个python程序再从文件里读出来。
    但是我们都知道,对于文件来说是没有字典这个概念的,所以我们只能将数据转换成字典放到文件中。
    你一定会问,将字典转换成一个字符串很简单,就是str(dic)就可以办到了,为什么我们还要学习序列化模块呢?
    没错序列化的过程就是从dic 变成str(dic)的过程。现在你可以通过str(dic),将一个名为dic的字典转换成一个字符串,
    但是你要怎么把一个字符串转换成字典呢?
    聪明的你肯定想到了eval(),如果我们将一个字符串类型的字典str_dic传给eval,就会得到一个返回的字典类型了。
    eval()函数十分强大,但是eval是做什么的?e官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。
    BUT!强大的函数有代价。安全性是其最大的缺点。
    想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。
    而使用eval就要担这个风险。
    所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
    
    为什么要有序列化模块
    为什么要有序列化模块

         序列化的目的:

           1、以某种存储形式使自定义对象持久化

           2、将对象从一个地方传递到另一个地方

           3、使程序更具维护性

      json模块 & pickle模块

        用于序列化的两个模块

          json:用于字符串和Python数据类型间进行转换

          pickle:用于Python特有的类型和Python的数据类型间进行转换

        json模块:

          json模块提供了四个功能:dumps、dump、loads、load

          优点:

            所有的语言都通用

          缺点:

            只支持非常少的数据类型

            对数据类型的约束很苛刻

              字典的key必须是字符串

              只支持:数字、字符串、列表、字典

    import json
    stu = {'name':'王瑞臣','sex':'male'}
    
    ret = json.dumps(stu)   # 序列化的过程
    print(stu,type(stu))    # {'name': '王瑞臣', 'sex': 'male'} <class 'dict'>
    print(ret,type(ret))    # {"name": "u738bu745eu81e3", "sex": "male"} <class 'str'>
    
    d = json.loads(ret)     # 反序列化的过程
    print('d--->',d,type(d))    # d---> {'name': '王瑞臣', 'sex': 'male'} <class 'dict'>
    
    
    lst = [1,2,3,4,'aaa','bbb']
    ret = json.dumps(lst)   # 序列化的过程
    print(lst,type(lst))    # [1, 2, 3, 4, 'aaa', 'bbb'] <class 'list'>
    print(ret,type(ret))    # [1, 2, 3, 4, 'aaa', 'bbb'] <class 'list'>
    
    d = json.loads(ret)     # 反序列化的过程
    print('d-->',d,type(d)) # d--> [1, 2, 3, 4, 'aaa', 'bbb'] <class 'list'>
    
    
    stu = {'name':'王瑞臣','sex':'male',1:('a','b')}
    ret = json.dumps(stu)   # 序列化的过程
    print(stu,type(stu))    # {'name': '王瑞臣', 'sex': 'male', 1: ('a', 'b')} <class 'dict'>
    print(ret,type(ret))    # {"name": "u738bu745eu81e3", "sex": "male", "1": ["a", "b"]} <class 'str'>
    d = json.loads(ret)     # 反序列化的过程
    print('d-->',d,type(d)) # d--> {'name': '王瑞臣', 'sex': 'male', '1': ['a', 'b']} <class 'dict'>
    # 把元祖变成列表了

     

    import json
    data = {'username':['李华','二愣子'],'sex':'male','age':16}
    json_dic2 = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False)
    print(json_dic2)
    '''
    sort_keys=True:将数据根据keys的值进行排序
    indent=4: 表示每行开头4个空格
    separators=(',',':'):分隔符,keys之间用“,”隔开,而key和value之间用“:”隔开
    ensure_ascii=False:当False时,非ascii码才能正常显示
    '''
    json的格式化输出

        pickle模块

          pickle模块提供了四个功能:dumps、dump(序列化,存)、loads(反序列化,读)、load  (不仅可以序列化字典,列表...可以把python中任意的数据类型序列化

          

    import pickle
    stu = {'name':'王瑞臣','sex':'male',1:('a','b')}
    ret = pickle.dumps(stu)   # 序列化的过程
    print(ret)  # b'x80x03}qx00(Xx04x00x00x00nameqx01X	x00x00x00xe7x8ex8bxe7x91x9exe8x87xa3qx02Xx03x00x00x00sexqx03Xx04x00x00x00maleqx04Kx01Xx01x00x00x00aqx05Xx01x00x00x00bqx06x86qx07u.'
    d = pickle.loads(ret)     # 反序列化的过程
    print(d,type(d))  # {'name': '王瑞臣', 'sex': 'male', 1: ('a', 'b')} <class 'dict'>
    
    class Course():
        def __init__(self,name,price):
            self.name = name
            self.price = price
    python = Course('python',29800)
    ret = pickle.dumps(python)    # 序列化的过程
    print(ret)  # b'x80x03c__main__
    Course
    qx00)x81qx01}qx02(Xx04x00x00x00nameqx03Xx06x00x00x00pythonqx04Xx05x00x00x00priceqx05Mhtub.'
    p = pickle.loads(ret)     # 反序列化的过程
    print(p.name,p.price)   # python 29800

        

          

       

  • 相关阅读:
    禁止网页右键、复制、另存为方法
    js循环99乘法口诀
    js点击判断显示或隐藏-21
    js下拉框-5
    js下拉框-4
    纯css下拉
    asp.net core 关于同步等待异步坑及解决办法
    net core http请求响应中间件 及全局异常中间件小计
    生产环境 前后端分离部署 https 跨域cors netcore3.1 部署小计
    csrediscore实现分布式锁 小计
  • 原文地址:https://www.cnblogs.com/yzh2857/p/9579848.html
Copyright © 2011-2022 走看看