zoukankan      html  css  js  c++  java
  • Python IO编程 序列化

    为什么使用序列化?

      因为程序运行期间,所有的变量都在内存中。可以随时修改变量,但程序一接触,所占的内存就会被操作系统回收。如果没有把修改后的'Bill'存储到磁盘上,下次重新运行程序,变量又被初始化为'Bob'

    通过将对象序列化,可以将其存储在变量或内存中,可以保存当时的状态,实现生命周期的延长,并在需要时再次将对这个对象读取出来。

    什么是序列化和反序列化?

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

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

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

     

    序列化

    python  提供了pickle 和 json 模块, 实现序列化和反序列化

    pickle:

        dumps:将对象序列化为bytes,然后写入文件

           loads:反序列化出对象

           dump: 直接将对象序列化写入文件

           load:   反序列化出对象

    序列化

    1、pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件

    2、pickle.dump()直接把对象序列化后写入一个file-like Object

    pickle.dumps()

    pickle.dump()

    import  pickle
    d = dict(name='Andy',age=18)
    byt = pickle.dumps(d)
    with open('test.txt','wb') as f:
        f.write(byt)

    import  pickle
    d = dict(name='Andy',age=18)
    with open('test.txt','wb') as f:
        pickle.dump(d,f)

    反序列化 

    把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用

    1、pickle.loads()方法反序列化出对象

    2、也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象

     

    with open('test.txt','rb') as f:
        byts = f.read()
        print(pickle.loads(byts))
        #{'name': 'Andy', 'age': 18}

    with open('test.txt','rb'as f:
        print(pickle.load(f))

    Json

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

    JSON和Python内置的数据类型

    JSON类型

    Python类型

    {}

    dict

    []

    list

    string

    str

    true/false

    True/False

    null

    None

    Python内置的json模块提供了非常完善的Python对象到JSON格式的转换

    转换为Json

    1、dumps() :将对象序列化为JSON字符串; 返回一个str,内容是标准的Json

    2、dump(): 将对象序列化为JSON字符串,然后写入文件

     Json反序列化为Python对象

    1、loads() :把JSON的字符串反序列化

    2、load()  :从文件中读取字符串并反序列化

    import json
    d = dict(name='Bob', age=20, score=88)
    print(json.dumps(d))
    #'{"age": 20, "score": 88, "name": "Bob"}'

    json_str = '{"age": 20, "score": 88, "name": "Bob"}'
    print(json.loads(json_str))
    # {'age': 20, 'score': 88, 'name': 'Bob'}

     

    由于JSON标准规定JSON编码是UTF-8,所以我们总是能正确地在Python的str与JSON的字符串之间转换。

    JSON进阶:类对象的序列化和反序列化

    import json
    class Student(object):
        def __init__(self, name, age, score):
            self.name = name
            self.age = age
            self.score = score

    s = Student('Bob', 20, 88)
    print(json.dumps(s))

    报错:TypeError: Object of type Student is not JSON serializable

    错误的原因是Student对象不是一个可序列化为JSON的对象。

    默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象。

    可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可:

    def student2dict(std):
        return {
            'name': std.name,
            'age': std.age,
            'score': std.score
        }

    print(json.dumps(s, default=student2dict))
    # {"name": "Bob", "age": 20, "score": 88}

    不过,下次如果遇到一个Teacher类的实例,照样无法序列化为JSON。我们可以偷个懒,把任意class的实例变为dict:

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

    因为通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。也有少数例外,比如定义了__slots__的class。

    同样的道理,如果我们要把JSON反序列化为一个Student对象实例,loads()方法首先转换出一个dict对象,然后,我们传入的object_hook函数负责把dict转换为Student实例:

    def dict2student(d):
        return Student(d['name'], d['age'], d['score'])

     

    def dict2student(d):
        return Student(d['name'], d['age'], d['score'])

    json_str = '{"age": 20, "score": 88, "name": "Bob"}'
    print(json.loads(json_str, object_hook=dict2student))
    # <__main__.Student object at 0x10cd3c190>

  • 相关阅读:
    C语言宏的定义和宏的使用方法(#define)
    C语言字符串拼接
    OC字符串与C语言字符串之间的相互转换
    C语言#include的用法
    NSSet集合
    NSArray 数组
    预定义宏,C语言预定义的宏详解
    主流C语言编译器介绍
    无法使用此电子邮件地址。请选择其他电子邮件地址
    可变大小、颜色边框、样式的UISwitch
  • 原文地址:https://www.cnblogs.com/AndyChen2015/p/11398608.html
Copyright © 2011-2022 走看看