工作中经常需要对一些数据进行传输,在Python中,万物皆对象,也就是说,需要对一些对象在网络中进行传输,必须要转换成为可以传输的字节码。
一般我都喜欢用一个中间缓存来保存一些数据对象,用的最多的是redis。对于常规的Python内置对象,用json数据解码成字节码,很是方便,调试中可以直接从缓存中进行查看。
假如用了pickle,这些数据都是转换了以后都是一些人类无法理解的字节码。
话说这次操作的是一个collection中的OrderedDict对象,我在将该类对象保存到缓存的时候,一般习惯用repr强制转换成字符结构,解码放入缓存,后续通过eval提取出数据对象。
a Out[25]: OrderedDict([('a', 1)]) repr(a) Out[26]: "OrderedDict([('a', 1)])"
就想上面显示的,当我在另外一个进程通过eval执行该字符串时,其实就是执行OrderedDict([('a', 1)])的表达式,这个时候OrderedDict是一个可调用对象,接入该进程中没有导入该对象,就会报错。
但经过我的测试,pickle就显的很强大,当你传输一个对象无论是Python内置的,还是三方导入的,当你传入一个pickle数据给另外一个数据时,他在还原实例的时候,随便帮你导入,需要的可调用对象。
简单的比方好了
import requests a = requests.Session()
这个requests是一个三方的包,a是一个实例对象,需要Session的可调用对象创建,当pickle.dumps完成以后,就变成了一串字节码。
当另外一个进程通过pickle.loads还原该对象的时候,你不需要手动前置导入import requests,在还原对象的过程中会自动帮你导入。
这个对于传输一些标准的Python内置对象与三方实例还是非常好用的。但自定义的实例肯定是不可以的。
总结来说,序列化传输还是根据实际的情况来使用最好,标准的数据用json最好,特殊一些的用repr与eval搭配也可行,如果不需要中间缓存看数据内容,pickle肯定是最佳方案。
最后再强调一次,任何对象序列化与反序列化之后,对象的内容是相等的,但对象已经不是原来的他,因为一个是另一个的拷贝,是在计算机两块不同的内存中,无论是否经过通信传输。