zoukankan      html  css  js  c++  java
  • 27. 序列化

    把变量从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling。序列化之后,就可以把序列化后的内容写入磁盘,或者通过网络传输到别的机器上。反过来,把变量内容从序列化的对象重新读到内存里称之为反序列化,即unpickling。

    ​Python提供了pickle模块来实现序列化。

    >>> import pickle
    >>> d = dict(name='Bob', age=20, score=88)
    >>> pickle.dumps(d)
    b'x80x03}qx00(Xx03x00x00x00ageqx01Kx14Xx05x00x00x00scoreqx02KXXx04x00x00x00nameqx03Xx03x00x00x00Bobqx04u.'
    

    ​pickle.dumps()方法把任意对象序列化成一个bytes,然后,就可以把这个bytes写入文件。或者用另一个方法pickle.dump()直接把对象序列话后写入一个file-like Object:

    >>> f = open('dump.txt', 'wb')
    >>> pickle.dump(d, f)
    >>> f.close()
    

    ​当我们要把对象从磁盘读到内存时,可以先把内容读到一个bytes,然后用pickle.loads()方法反序列化出对象,也可以直接用pickle.load()方法从一个file-like Object中直接反序列化出对象。

    >>> f = open('dump.txt', 'rb')
    >>> d = pickle.load(f)
    >>> f.close()
    >>> d
    {'age': 20, 'score': 88, 'name': 'Bob'}
    

    JSON

    1. dict -> json / json -> dict

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

    • 把Python对象变成一个JSON:
    >>> import json
    >>> d = dict(name='Bob', age=20, score=88)
    >>> json.dumps(d)
    '{"age": 20, "score": 88, "name": "Bob"}'
    

    dumps()方法返回一个str,内容就是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like Object。

    • 把JSON反序列化为Python对象:

    用loads()或者对应的load()方法,前者把JSON的字符串反序列化,后者从file-like Object中读取字符串并反序列化:

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

    2. class -> json / json -> class

    ​Python的dict对象可以直接序列化为JSON的{},不过,很多时候,我们更喜欢用class表示对象,比如定义Student类,然后序列化:

    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))
    

    ​为默认情况下,dumps()方法不知道如何将Student实例变为一个JSON的{}对象。可选参数default就是把任意一个对象变成一个可序列为JSON的对象,我们只需要为Student专门写一个转换函数,再把函数传进去即可:

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

    ​ 这样,Student实例首先被student2dict()函数转换成dict,然后再被顺利序列化为JSON

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

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

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

    ​因为通常class的实例都有一个__dict__属性,它就是一个dict,用来存储实例变量。

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

    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>
    
  • 相关阅读:
    HDU 2955 Robberies(01背包)
    HDU 2602 Bone Collector(01背包)
    HUST 1352 Repetitions of Substrings(字符串)
    HUST 1358 Uiwurerirexb jeqvad(模拟解密)
    HUST 1404 Hamming Distance(字符串)
    HDU 4520 小Q系列故事――最佳裁判(STL)
    HDU 2058 The sum problem(枚举)
    【破解】修改程序版权、添加弹窗
    HDU 1407 测试你是否和LTC水平一样高(枚举)
    HDU 1050 Moving Tables(贪心)
  • 原文地址:https://www.cnblogs.com/BigMario/p/13577911.html
Copyright © 2011-2022 走看看