• 技术文章 >Python技术 >Python高级

    一文了解Python序列化

    爱喝马黛茶的安东尼爱喝马黛茶的安东尼2019-11-29 15:27:31转载2004

    程序运行时,所有的变量都储存在内存中,程序结束运行时,这些占用的内存将被系统回收,无法长期储存,将这些变量转换为可储存或可通过网络传输的过程称之为序列化(pickling),序列化后就可以将它们储存在磁盘或通过网络进行传输。

    1.pickle序列化

    Python提供了pickle模块来实现变量的序列化,这个模块可以将变量转换成字节码(bytes)形式储存,还能将储存的序列化字节码重新还原成数据对象;

    注意:pickle仅能用于python程序之间交换数据,且不同的版本之间并不兼容,需要和其他程序进行通信时,请使用json序列化,它可以在不同编程语言间共享数据。

    a.pickle普通对象序列化

    先来看一个小实例,使用pickle模块,将几个不同的对象序列化,这些序列化后的对象可用于网络传输或储存到磁盘文件中:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    #!/usr/bin/env python3

    #coding=utf-8

    import os

    import pickle

    #创建一个字典对象和一个字符串对象

    d=dict(one=1,two=2,three=3)

    s="python"

    print(d) #输出{'three': 3, 'two': 2, 'one': 1}

    print(s) #输出

      

    #将这两个对象序列化,nd和ns仅保存在内存中,可用于网络传输

    nd=pickle.dumps(d)

    ns=pickle.dumps(s)

    print(nd) #输出字节码"b'\x80\x03}q\x00...."

    print(ns) #输出字节码"b'\x80\x03X\x11...."

      

    #将序列化后的对象重新还原成数据(假设接收端接收到这些数据后,就能够这样还原)

    nd=pickle.loads(nd)

    ns=pickle.loads(ns)

    print(nd) #输出{'three': 3, 'two': 2, 'one': 1}

    print(ns) #输出

      

    #创建一个文件testfile,接收字节码(wb),将d对象中的数据写入其中,

    #用于本地不同应用程序之间数据交换(此时如果我们打开testfile文件,

    #就会看到一些类似乱码一样的字符,实际上是d对象序列化后的数据)

    with open("testfile","wb") as f1:

        pickle.dump(d,f1)

      

    #从testfile文件中读取字节码,还原成数据

    if os.path.isfile("testfile"):

        with open("testfile","rb") as f2:

            print(f2.read()) #输出"b'\x80\x03}q\x0...."

    #因为上一步读取了数据,指针位置要重新设置成起始位置,

    #这仅仅是为了演示给大家看,上面print和seek这两句可以不写

            f2.seek(0)

            d=pickle.load(f2) #读取f2中的数据还原

            print(d) #输出{'three': 3, 'two': 2, 'one': 1}

    总结:仅在内存中序列化和还原,使用dumps()和loads(),要将数据序列化后保存到文件中使用dump(),从文件中还原数据使用load(),两者只有一个s的区别,注意不要混淆。

    b.pickle类序列化

    有时候我们可能要传输或保存一个类对象与其中所有的数据,python中实现类的序列化十分简单,与对象序列化没有什么区别,请看下面的实例:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    #!/usr/bin/env python3

    #coding=utf-8

    import pickle

    ########

    class A:

        #--------

        def __init__(self,name="py",website="python"):

            self.name=name

            self.website=website

    x=A()

    x.name="晴刃"

      

    #序列化类实例x,可用于网络传输

    nx=pickle.dumps(x)

    print(nx) #输出"b'\x80\x03c__main__...."

      

    #还原数据

    nx=pickle.loads(nx)

    print(nx) #输出"<__main__.A object at 0x7f43c995c080>"

      

    #将类对象序列化后保存到磁盘文件中,可用于程序间数据交换

    with open("testfile","wb") as f1:

        pickle.dump(x,f1)

      

    #读取文件中的数据还原

    with open("testfile","rb") as f1:

        y=pickle.load(f1)

    print(y.name) #输出"晴刃"

    print(y.website) #输出

    2.json序列化

    如果要在不同的编程语言之间传递对象,可以使用python的json模块对数据进行序列化,json序列化后所有数据都被表示成字符串形式,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输,但在类数据转换时会稍微有点麻烦,没有pickle那么方便。

    a.json普通对象序列化

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    #!/usr/bin/env python3

    #coding=utf-8

    import json

      

    #创建一个字典对象和一个浮点数对象

    d=dict(one=1,two=2,three=3)

    f=3.14

      

    print(type(d)) #<class 'dict'>

    print(type(f)) #<class 'float'>

      

    #普通对象的序列化与pickle相同

    nd=json.dumps(d)

    nf=json.dumps(f)

      

    #转换后所有对象都变成了字符串类型<class 'str'>

    print(type(nd))

    print(type(nf))

    print(nd) #"{"three": 3, "two": 2, "one": 1}"

    print(nf) #"3.14"

      

    #还原数据

    nd=json.loads(nd)

    nf=json.loads(nf)

    print(type(nd)) #<class 'dict'>

    print(type(nf)) #<class 'float'>

      

    #将d对象序列化后储存到testfile文件中

    with open("testfile","w") as f1:

        json.dump(d,f1)

      

    #从testfile文件中读取数据并还原

    with open("testfile","r") as f1:

        y=json.load(f1)

        print(type(y)) #<class 'dict'>

    b.json类序列化

    使用json序列化类会稍显复杂,因为json的dump方法不知道如何将一个类转换成字符串,需要我们自己指定一个转换函数,请看下面的实例:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    #!/usr/bin/env python3

    #coding=utf-8

    import json

      

    class A(object):

        def __init__(self,name="py",website="python"):

            self.name=name

            self.website=website

    #初始化一个类实例

    a=A()

      

    #创建一个函数,将类A中的对象和数据转换成字典的形式返回

    def  classA2dict(c):

        return {"name":c.name,"website":c.website}

      

    #将a使用json序列化,参数default告诉python解释器,将前面的对象a传递给后面的classA2dict函数处理,

    #classA2dict函数会返回一个字典类型,这个类型中包含了实例a中所有对象和数据的"键值对"

    #然后dumps函数将这个返回的字典类型序列化成字符串类型

    x=json.dumps(a,default=classA2dict)

    #如果想偷懒不写classA2dict函数,有一种简便方法,使用匿名函数,并且调用基类的__dict__函数,

    #这个函数会完成和classA2dict函数相同的功能,即将一个类的所有属性转换成字典"键值对"的形式

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

      

    print(type(x)) #<class 'str'>

    print(x) #"{"website": "python", "name": "py"}"

      

    #字典类型转换成类返回

    def dict2classA(d):

        return A(d["name"],d["website"])

      

    #将json序列后的数据还原成类,object_hook参数将x转换成字典类型,并传递给dict2classA函数处理,

    #dict2classA函数会读取这个字典中的每个键,将值传入A类进行初始化,返回一个类对象

    x=json.loads(x,object_hook=dict2classA)

    print(type(x)) #<class '__main__.A'>

    print(x.website)

      

    #将序列化的类写入文件testfile中

    with open("testfile","w") as f1:

        json.dump(a,f1,default=classA2dict)

    #读取testfile中的数据还原

    with open("testfile","r") as f2:

        y=json.load(f2,object_hook=dict2classA)

        print(y.name)

    众多python培训视频,尽在python学习网,欢迎在线学习!

    本文转自:https://www.jianshu.com/p/f4cfa19abca4

    专题推荐:python 序列化
    上一篇:八个数据清洗的Python代码(复制即可使用) 下一篇:Python:支持向量机SVM的使用

    相关文章推荐

    • 详解Python序列化模块pickle和json的使用和区别• python怎么序列化

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网