zoukankan      html  css  js  c++  java
  • Python学习笔记-Day22-内置方法及序列化模块

    内容大纲

    一、内置方法__new__/__del__/__len__/__hash__/__eq__

    二、序列化模块pickle和json

    一、内置方法

    1、__new__:构造方法

    在执行__init__之前,类会调用ibject中的__new__方法创建一个对象空间

    class Foo:
        def __init__(self):
            print('init')
        def __new__(cls, *args, **kwargs):
            print('new')
            return object.__new__(cls)
    f = Foo()
    
    结果:init
    new

    重要应用:单例模式

    class Foo:
        __instance = None
        def __init__(self,name,age):
            self.name = name
            self.age = age
            self.lst = [name]
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None:
                cls.__instance = object.__new__(cls)
            return cls.__instance
    obj1 = Foo('小明',23)
    obj2 = Foo('小红',24)
    print(obj1.name,obj1.age)  #  小红 24
    print(obj1.lst)  #  ['小红']

    2、__del__:析构方法,当对象在内存中被释放的时候,会主动触发这个方法,当对象被删除的时候,会先触发这个方法在删除对象,这个方法通常用于关闭文件,归还系统资源等,到程序结束总会执行这个方法

    class Foo:
        def __del__(self):
            print('执行我啦')
    obj = Foo()
    del obj
    print('结束')
    结果:执行我啦
    结束

    3、__len__:可以使用len()函数计算对象的长度

    class Class:
        def __init__(self,course):
            self.course = course
            self.student = []
        def __len__(self):
            return len(self.student)
    python = Class('python')
    python.student.append('小明')
    python.student.append('小红')
    python.student.append('小黑')
    print(len(python))  #  3

    4、__eq__:可根据eq中的条件判断两个对象是否相等

    class Foo:
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __eq__(self, other):
            if self.name == other.name:
                return True
            else:
                return False
    obj1 = Foo('小明',23)
    obj2 = Foo('小红',23)
    obj3 = Foo('小明',24)
    print(obj1==obj2)  #  False
    print(obj1==obj3)  #  True

    5、__hash__:根据自定义的条件计算对象的哈希值

    class Foo:
        pass
    obj = Foo()
    print(hash(obj))  #-9223371856450203262
    
    class Foo:
        def __hash__(self):
            return hash('foo')
    obj = Foo()
    print(hash(obj))  #-3494245336101080890

    哈希算法的特点:

    1、同一个程序中,相同的值的哈希值是相同的

    2、同一个程序中,不同的值的哈希值总是不同的(也有一些例外)

    字典寻址快的原因:首先计算键的hash值,得出内存地址,根据内存地址找到value

    set的去重原理:① 首先计算元素的哈希值,得到内存地址

            ② 到这个内存地址上去看,如果没有值,就把这个值放到这个内存地址上;如果有值,判断两个值是否相等,相等的话就丢弃后一个值,不想等的话进行二次寻址找另一块内存去存这个值

    例题:100个员工的去重,姓名和性别相同就是同一个员工

    class Staff:
        def __init__(self,name,age,sex,department,):
            self.name = name
            self.age = age
            self.sex = sex
            self.department = department
        def __eq__(self, other):
            if self.name == other.name and self.sex == other.sex:
                return True
        def __hash__(self):
            return hash(self.name + self.sex)
    name_lst = ['小明','小红','小黑','小白']
    lst = []
    for i in range(100):
        name = name_lst[i%4]
        obj = Staff(name,i,'male','python')
        lst.append(obj)
    set1 = set(lst)
    for i in set1:
        print(i.name,i.age)
    
    #结果:
    小明 0
    小黑 2
    小红 1
    小白 3

    二、序列化模块

    什么是模块?

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

      内置模块:安装python解释器的时候自动安装上的

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

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

    什么是序列?

      list、dict、str、bytes就是序列

    什么是序列化?

      将一个数据类型类型转化成str或bytes类型就是序列化

    为什么要序列化?

      当你需要将一种数据类型进行存储或网络传输的时候,需要转化成str或bytes类型

    json和pickle模块就是专门将其他数据类型转化成字符串或bytes类型进行存储和网络传输用

    1、json:

    json的特点:① 能够在所有语言中通用

            ② 能转化的类型有限,只能转化列表、字典、字符串、数字(元组会被转化成列表)

            ③ 对字典的要求很高,键必须是字符串类型,且反序列化的时候必须不能有单引号,全部变成双引号

    json的用法(4种):

      json.dumps(dict/list):序列化方法,将dict类型或list类型转化成字符串类型

      json.loads(str):反序列化方法,将str类型重新转化成dict/list

      json.dump(序列,f):序列化方法,将dict/list ---->str并写入文件

      json.load(f):反序列化方法,将文件中的字符串类型的数据重新转化成dict/list

    举例:

    import json
    stu={'name':'小红','age':23}
    ret = json.dumps(stu,ensure_ascii=False)  # ensure_ascii=False可以显示中文
    print(ret,type(ret))  # {"name": "小红", "age": 23} <class 'str'>
    
    dic = json.loads(ret)
    print(dic,type(dic))  #  {'name': '小红', 'age': 23} <class 'dict'>
    import json
    stu={'name':'小红','age':23}
    with open('file',mode='w',encoding='utf-8') as f:
        json.dump(stu,f,ensure_ascii=False)
    with open('file',encoding='utf-8') as f1:
        ret = json.load(f1)
        print(ret)  # {'name': '小红', 'age': 23}

    注意:多次进行dump,load时会报错

    json的格式化:可以百度json的格式化工具

    import json
    data = {'username': ['李华', '二愣子'], 'sex': 'male', 'age': 16}
    ret = json.dumps(data,sort_keys=True,indent=4,separators=(',',':'),ensure_ascii=False)
    print(ret)
    # {
    #     "age":16,
    #     "sex":"male",
    #     "username":[
    #         "李华",
    #         "二愣子"
    #     ]
    # }

    2、pickle

    pickle的特点:

      ① 只能在python中使用

      ② 可以序列化任意的数据类型

      ③ 进行文件操作时必须是‘+b‘的模式

      ④ load对象的时候,对象所属的类必须在内存中

      ⑤ 支持多次dump和多次load,但是需要异常处理。except EOFError

    举例:

    # 序列化和反序列化一个字典
    import pickle
    stu={'name':'小红','age':23}
    str1 = pickle.dumps(stu)
    print(str1,type(str1))  #是个bytes类型的数据
    dic = pickle.loads(str1)
    print(dic)  #  {'name': '小红', 'age': 23}
    
    # 序列化和反序列化一个对象
    class Course:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    python = Course('python',12345)
    ret = pickle.dumps(python)
    print(ret)
    obj = pickle.loads(ret)
    print(obj.name)  # python
    import pickle
    class Course:
        def __init__(self,name,age):
            self.name = name
            self.age = age
    python = Course('python',12345)
    linux = Course('linux',1225)
    java = Course('java',3433)
    with open('file3','ab') as f:
        pickle.dump(python,f)
        pickle.dump(linux,f)
        pickle.dump(java,f)
    
    with open('file3','rb') as f1:
        while True:
            try:
                obj = pickle.load(f1)
                name = obj.name
                print(name)
            except EOFError:
                break
  • 相关阅读:
    封装

    如何通过命令行窗口查看sqlite数据库文件
    标签控件
    信息提示框
    循环
    数组
    switch
    成员局部变量
    变量
  • 原文地址:https://www.cnblogs.com/tian-tian/p/9640925.html
Copyright © 2011-2022 走看看