pickle用法,以及在multiprocessing中的雷区
Process传参报错pickle
process多进程的过程涉及pickle,俗称序列化,多进程传参数会自动将参数序列化,pickle.dumps()
我在开启多进程传参过程中传递了不可序列化的对象——ssh初始化的对象,他是一个Paramiko实例对象,
导致报错TypeError: can't pickle _thread.lock objects
在多进程传参时要避免雷区,就首先要
检测自己的参数能不能序列化,在传参前检测一下 pickle.dumps() 是否会报错
下面是我的代码,其中,p是proxiesIp类的初始化,proxiesIp类是自定义的一个初始化ssh的实例对象
if __name__ == '__main__':
freeze_support()
# 初始化代理ip
p = proxiesIp()
# p.start_tiny_proxy()
p.adsl_restart()
p = pickle.dumps(p)
out:
Traceback (most recent call last):
File "F:/alisonProject/User-Profile-Recommend/Alison_user_profile_movie_recommend/src/test_process.py", line 20, in <module>
p = pickle.dumps(p)
TypeError: can't pickle _thread.lock objects
和我开启多进程报错内容一毛一样是不?
现在检验一下正常可以序列化的值
if __name__ == '__main__':
freeze_support()
user_list = [1,2,3,2,5]
user_pickle = pickle.dumps(user_list)
没有报错,我给他序列化以后的东西打印了一下:
b'\x80\x03]q\x00(K\x01K\x02K\x03K\x02K\x05e.'
是个二进制
那么,pickle可以序列化哪些对象呢
了解一下pickle:
如果希望透明地存储 Python 对象,而不丢失其身份和类型等信息,则需要某种形式的对象序列化:它是一个将任意复杂的对象转成对象的文本或二进制表示的过程。
同样,必须能够将对象经过序列化后的形式恢复到原有的对象。在 Python 中,这种序列化过程称为 pickle,
可以将对象 pickle 成字符串、磁盘上的文件或者任何类似于文件的对象,也可以将这些字符串、文件或任何类似于文件的对象 unpickle 成原来的对象
pickle可以序列化的对象
None
,True
,False
- integers, floating point numbers, complex numbers
- strings, bytes, bytearrays
- tuples, lists, sets, dictionaries containing only picklable objects
- functions defined at the top level of a module (using
def
, notlambda
) - built-in functions defined at the top level of a module
- classes that are defined at the top level of a module
- instances of such classes whose
__dict__
or the result of calling__getstate__()
is picklable (see section Pickling Class Instances for details).
pickle的使用
- pickle.dump(obj,file) 将一个对象obj实例化以后存到file里,file = open(filename,'w'),经常适用于在pandas处理数据中存储 庞大的非结果的中间数据
- p = pickel.dumps(obj) 将一个对象直接序列化
- obj = pickle.load(pfile) 从pickle.dump存储的序列化内容的文件加载出来并转化为pickle.dump前的对象
- obj = pickle.loads(p) 将pickle.dumps后的序列化对象转为原来的对象
上面所说的对象都是实例对象哦~~~~~
欢迎交流~~!