python读书笔记 (十) 数据存储

16.1 serialization

marshal

通常不建议用来存储自定义数据。
支持:None, bool, int, long, float, complex, str, unicode, tuple, list, set, frozenset, dict,
code objects, StopIteration。容器元素必须是所支持类型,不能是递归引用

>>> s = dumps((1, 2, 3))
>>> s
b'\xa9\x03\xe9\x01\x00\x00\x00\xe9\x02\x00\x00\x00\xe9\x03\x00\x00\x00'
>>> loads(s)
(1, 2, 3)
>>> 


>>> with open('test.dat', 'wb') as f:
...     dump((1, 2, 3), f)
... 
17
>>> with open('test.dat', 'rb') as f:
...     print(load(f))
... 
(1, 2, 3)
>>> 
>>> help(dump)

 

pickle
支持用户自定义类型,支持三种协议版本:

• 0: 使用可显示的 ASCII 字符编码,便于阅读和手工编辑。(默认)
• 1: 兼容早期 Python 版本的二进制格式。
• 2: 最有效的二进制编码格式

>>> import pickle
>>> s = 'hello, world'
>>> d = pickle.dumps(s)
>>> 
>>> d
b'\x80\x03X\x0c\x00\x00\x00hello, worldq\x00.'
>>> pickle.loads(d)
'hello, world'

同样有读写文件的 dump、load 函数。看看支持的数据类型:
• None, True, False
• int, long, float, complex
• str, unicode
• tuple, list, set, and dict (元素必须是支持类型)
• function (模块级别的函数)
• classe (模块级别的自定义类,非嵌套)
• instance (有 __dict__ 属性,或者实现 pickle protocol 协议)

>>> class Data(object):
...     def __init__(self, x,y):
...             print('__init__')
...             self._x = x
...             self._y = y
... 
>>> 
>>> d = Data(100, 200)
__init__
>>> s = pickle.dumps(d, 2)
>>> s
b'\x80\x02c__main__\nData\nq\x00)\x81q\x01}q\x02(X\x02\x00\x00\x00_xq\x03KdX\x02\x00\x00\x00_yq\x04K\xc8ub.'
>>> d2 = pickle.loads(s)
>>> d2.__dict__
{'_x': 100, '_y': 200}

利用 pickle protocol 可以控制序列化的细节。比如不保留_y字段

import pickle
class Data(object):
    def __init__(self, x, y):
        self._x = x
        self._y = y

    def __getstate__(self):
        d = self.__dict__.copy()
        print('__getstate__')
        del d['_y']
        return d

    def __setstate__(self, state):
        print('__setstate__: ', state)
        self.__dict__.update(state)

d = Data(10, 20)
s = pickle.dumps(d, 2)    # __getstate__
d2 = pickle.loads(s)      # __setstate__:  {'_x': 10}
print(d2.__dict__)        # {'_x': 10}

在使用pickle序列化时,Pickle 每次序列化生成的字符串有独立头尾,pickle.load() 只会读取一个完整的结果。如果多次pickle.dump,则需要多次dump.load才能读取完成。

if __name__ == '__main__':
    f = open('data', 'wb')
    pickle.dump([1, 2, 3], f)
    pickle.dump('hello', f)
    pickle.dump({'hi': 'haha'}, f)
    f.close()
    
    with open('data', 'rb') as f:
        try:
            while True:
                print(pickle.load(f))
        except EOFError:
            print('加载完毕')

 

转载于:https://my.oschina.net/acutesun/blog/994124

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值