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.到这个内存地址上查看
    #         如果这块内存中没有值
    #             将这个元素存到对应的内存地址上
    #         如果这块内存中已经有值
    #             判断这两个值是否相等
    #                 如果相等 就舍弃后面的值
    #                 如果不相等 就二次寻址再找一个新的空间来存储这个值
    # 员工类
    # 姓名 年龄 性别 部门
    # 转岗位后
    # 姓名 年龄变化了 性别 部门变化了
    # 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
                 json.dumps(): 对json进行编码,把数据类型转换成字符串。

                 json.dump():对json进行编码, 把数据类型转换成字符串,并存储在文件中。

                 json.loads(): 对json进行解码,把字符串转换成数据类型 。
                 json.load(): 把文件打开,对json进行解码,从字符串转换成数据类型。

          优点:

            所有的语言都通用

          缺点:

            只支持非常少的数据类型

            对数据类型的约束很苛刻

              字典的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码才能正常显示
    '''

        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
  • 相关阅读:
    leetcode 155. Min Stack 、232. Implement Queue using Stacks 、225. Implement Stack using Queues
    leetcode 557. Reverse Words in a String III 、151. Reverse Words in a String
    leetcode 153. Find Minimum in Rotated Sorted Array 、154. Find Minimum in Rotated Sorted Array II 、33. Search in Rotated Sorted Array 、81. Search in Rotated Sorted Array II 、704. Binary Search
    leetcode 344. Reverse String 、541. Reverse String II 、796. Rotate String
    leetcode 162. Find Peak Element
    leetcode 88. Merge Sorted Array
    leetcode 74. Search a 2D Matrix 、240. Search a 2D Matrix II
    Android的API版本和名称对应关系
    spring 定时任务执行两次解决办法
    解析字符串为泛型的方法
  • 原文地址:https://www.cnblogs.com/zyling/p/12779263.html
Copyright © 2011-2022 走看看