zoukankan      html  css  js  c++  java
  • 序列化的两个模块(json和pickle)

    到底什么是序列化(picking)呢?

      我们把变量从内存中变成可存储或传输的过程称之为序列化

      序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。

      反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling

    json和pickle

      json和pickle模块,两个都是用于序列化的模块

    json

    #json 是通用的,可以在各种语言里进行交互,只是一个简单的序列化方法
    #json把python对象转化成字符串,仅限于简单的数据类型,例如列表,字典,元组等

    pickle

    #pickle是python中独有的序列化模块,pickle支持序列化所有python数据类型,以二进制的方式序列化

    pickle

    import pickle
    d=[1,2,'a','b']
    print(pickle.dumps(d))
    print(type(pickle.dumps(d)))
    
    #执行结果
    b'x80x03]qx00(Kx01Kx02Xx01x00x00x00aqx01Xx01x00x00x00bqx02e.'
    <class 'bytes'>

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

        dumps和dump都是进行序列化,而loads和load则是反序列化

      dumps将所传入的变量的值序列化为一个bytes,然后,就可以将这个bytes写入磁盘或者进行传输。

      而dump则更加一步到位,在dump中可以传入两个参数,一个为需要序列化的变量,另一个为需要写入的文件。

    import pickle
    
    info={
        'name':'牛魔王',
        'age':'22',
        'sex':''
    }
    f=open('pickle_text','wb')
    f.write(pickle.dumps(info))# -->=pickle.dump(info,f)
    f.close()
    View Code

      反序列化:loads当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用loads方法反序列化出对象,也可以直接用load方法直接反序列化一个文件。

    import pickle
    f=open('pickle_text','rb')
    print(pickle.loads(f.read()))#pickle.loads(f.read())等同于pickle.load(f)
    f.close()
    View Code

    json

      如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。

      json中的方法和pickle中差不多,也是dumps,dump,loads,load。使用上也没有什么区别,区别在于,json中的序列化后格式为字符。

    import json
    info={
        'name':'Mike',
        'age':'22',
        'sex':'Man'
    }
    print(json.dumps(info))
    
    #执行结果
    {"age": "22", "name": "Mike", "sex": "Man"}

    dumps:

    import json
    info={
        'name':'Mike',
        'age':'22',
        'sex':'Man'
    }
    
    f=open('json_text','w',encoding='utf-8')
    f.write(json.dumps(info))
    f.close()
    View Code

    loads:

    import json
    f=open('json_text','r',encoding='utf-8')
    data=json.loads(f.read())
    print(data['age'])
    f.close()
    View Code

      因为python中一切事物皆对象,所有对象都是基于类创建的,所以,‘类’在python中占据了相当大的比重。我们能否将类的实例进行序列化呢?

    class student(object):
        def __init__(self,name,age,course):
            self.name=name
            self.age=age
            self.course=course
    a=student('Mike',24,'male')
    import json
    json.dumps(a)
    
    TypeError: <__main__.student object at 0x01261670> is not JSON serializable #出错了

      难道真的序列化不了?

      其实前面的代码之所以无法把student类实例序列化为JSON,是因为默认情况下,dumps方法不知道如何将student实例变为一个JSON的'{}'对象。

    我们需要’告诉‘json模块如何转换。

    class student(object):
        def __init__(self,name,age,course):
            self.name=name
            self.age=age
            self.course=course
    a=student('Mike',24,'male')
    
    def st_to_dict(a):
        return {'name': a.name, 'age': a.age, 'course': a.course}
    
    import json
    print(json.dumps(a, default=st_to_dict))  # default参数就是告知json如何进行序列化

    #执行结果
    {"name": "Mike", "age": 24, "course": "male"}

    当然,如果我们每定义一个类,还得再定义一下这个类的实例转换为字典的函数实在是太麻烦了!!我们有一个一劳永逸的办法。

    print(json.dumps(a, default=lambda obj: obj.__dict__))

    #执行结果
    {"age": 24, "name": "Mike", "course": "male"}

    其中的__dict__不需我们在类中定义,因为通常class的实例都有一个__dict__属性,它就是一个字典,用来存储实例变量。

    print(a.__dict__)
    
    #执行结果
    {'age': 24, 'name': 'Mike', 'course': 'male'}
  • 相关阅读:
    ida动态调试--反反调试
    python读取配置文件
    问题解决:局域网内,为啥别人ping不到我的IP
    完全卸载MySQL
    JDK环境配置
    win10无法运行Vmware,怎么办
    查看ie版本
    公开的免费WebService接口分享,用于做接口练习
    SVN更改地址
    Loadrunner录制步骤及说明
  • 原文地址:https://www.cnblogs.com/freely/p/6411692.html
Copyright © 2011-2022 走看看