zoukankan      html  css  js  c++  java
  • python: 序列化/反序列化及对象的深拷贝/浅拷贝

    一、序列化/反序列化

    python中内置了很多序列化/反序列化的方式,最常用的有json、pickle、marshal这三种,示例用法如下:

    import json
    import pickle
    import marshal
    
    author1 = {"name": "菩提树下的杨过", "blog": "http://yjmyzz.cnblogs.com/", "title": "架构师", "pets": ["dog", "cat"]}
    
    # json序列化
    json_str = json.dumps(author1)
    print("json=>
    ", json_str)
    
    # json字符串反序列化
    author2 = json.loads(json_str)
    
    # pickle序列化
    pickle_str = pickle.dumps(author1)
    print("pickle=>
    ", pickle_str)
    
    # pickle字符串反序列化
    author3 = pickle.loads(pickle_str)
    
    # marshal序列化
    marshal_str = marshal.dumps(author1)
    print("marshal=>
    ", marshal_str)
    
    # marshal反序列化
    author4 = marshal.loads(marshal_str)
    
    print("
    ",
          id(author1), "
    ",
          id(author2), "
    ",
          id(author3), "
    ",
          id(author4), "
    ",
          author1, "
    ",
          author2, "
    ",
          author3, "
    ",
          author4)
    
    with open("json.txt", "w") as file1:
        json.dump(author1, file1)
    
    with open("pickle.txt", "wb") as file2:
        pickle.dump(author1, file2)
    
    with open("marshal.txt", "wb") as file3:
        marshal.dump(author1, file3)  

    输出:

    json=>
     {"name": "u83e9u63d0u6811u4e0bu7684u6768u8fc7", "blog": "http://yjmyzz.cnblogs.com/", "title": "u67b6u6784u5e08", "pets": ["dog", "cat"]}
    pickle=>
     b'x80x03}qx00(Xx04x00x00x00nameqx01Xx15x00x00x00xe8x8fxa9xe6x8fx90xe6xa0x91xe4xb8x8bxe7x9ax84xe6x9dxa8xe8xbfx87qx02Xx04x00x00x00blogqx03Xx1ax00x00x00http://yjmyzz.cnblogs.com/qx04Xx05x00x00x00titleqx05X	x00x00x00xe6x9exb6xe6x9ex84xe5xb8x88qx06Xx04x00x00x00petsqx07]qx08(Xx03x00x00x00dogq	Xx03x00x00x00catq
    eu.'
    marshal=>
     b'xfbxdax04namexf5x15x00x00x00xe8x8fxa9xe6x8fx90xe6xa0x91xe4xb8x8bxe7x9ax84xe6x9dxa8xe8xbfx87xdax04blogxfax1ahttp://yjmyzz.cnblogs.com/xdax05titlexf5	x00x00x00xe6x9exb6xe6x9ex84xe5xb8x88xdax04pets[x02x00x00x00xdax03dogxdax03cat0'
    
     4307564944 
     4309277360 
     4307565016 
     4309277432 
     {'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']} 
     {'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']} 
     {'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']} 
     {'name': '菩提树下的杨过', 'blog': 'http://yjmyzz.cnblogs.com/', 'title': '架构师', 'pets': ['dog', 'cat']}
    

    注:api的方法名还是很好记的,dump/dumps意为“倒垃圾”,把对象向xxx里一倒,就算序列化完成了。反之load/loads即从字符串或文件中装载(还原)对象。特别要值得一提的是:pickle、marshal存在安全问题,如果装载的字符串或文件里,包含有精心设计的恶意代码,会让恶意代码执行(关于反序列化的漏洞,大家可以上网查一下,有很多类似的介绍)。另外从序列化后的字符串大小来看,默认情况下,就本示例而言,json序列化后的字符串长度最小,so,综合来看,推荐同学们使用json序列化/反序列化

    二、深拷贝、浅拷贝

    import copy
    
    list_1 = [1, 2, 3, [4, 5]]
    
    list_2 = copy.copy(list_1)  # 浅拷贝
    
    list_3 = copy.deepcopy(list_1)  # 深拷贝
    
    list_2[3][0] = 99
    
    print("
    ", list_1, "
    ", list_2, "
    ", list_3)
    
    list_3[3][1] = 100
    
    print("
    ", list_1, "
    ", list_2, "
    ", list_3)
    

      输出:

     [1, 2, 3, [99, 5]] 
     [1, 2, 3, [99, 5]] 
     [1, 2, 3, [4, 5]]
    
     [1, 2, 3, [99, 5]] 
     [1, 2, 3, [99, 5]] 
     [1, 2, 3, [4, 100]]
    

      当一个对象里的子元素本身也是复杂元素时,浅拷贝不会为这种复杂的子元素生成全新的实例,但深拷贝可以。下面的内存分布示意图有助于大家理解:

    list_2是list_1浅拷贝生成的对象,对于第4个元素,都是指向同一个列表[4,5],所以list_2修改了[4,5]中的第1个元素为99后,list_1也受到影响。list_3则是深拷贝的结果,所有元素都是独立的新实例,因此修改list_3里的任何元素,都不会影响list_1、list_2

    参考文档:

    1. https://docs.python.org/3/library/pickle.html
    2. https://docs.python.org/3/library/json.html
    3. https://docs.python.org/3/library/marshal.html
    4. https://docs.python.org/3/library/copy.html

  • 相关阅读:
    水木→函数式编程语言→lisp是不是主要用来编网站的?
    OpenMP 维基百科,自由的百科全书
    一个实际的Lisp项目开发心得 albert_lee的产品技术空间 博客频道 CSDN.NET
    ...
    OpenMPI
    Debian下安装NetBeans
    Linux Socket学习(十七)
    Linux Socket学习(十四)
    Debian下安装Latex
    Debian下安装virtualbox
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/python-serialization-and-object-copy.html
Copyright © 2011-2022 走看看