控制 Python 类的序列化过程
问题
有的类是不支持在多进程间传递的,如果非要这么做,可能会引发奇怪的现象。比如下面这段代码:
from concurrent.futures import ProcessPoolExecutor, as_completed
from pymysql import connect
class MySqlDatabase(object):
def __init__(self, host='127.0.0.1', port=3306, user='root', pwd='', db=None):
self.host = host
self.port = port
self.user = user
self.pwd = pwd
self.db = db
self.conn = self.connect()
def connect(self):
return connect(host=self.host, port=self.port, user=self.user, password=self.pwd, database=self.db)
def runquery(self, q):
with self.conn.cursor() as cur:
cur.execute(q)
return cur
def run_in_pool(db, sql):
print(db.runquery(sql))
def run():
quires = ['show tables',
'select * from user']
db = MySqlDatabase(pwd='1234', db='mysql')
with ProcessPoolExecutor() as e:
fs = [e.submit(run_in_pool, db, q) for q in quires]
for f in as_completed(fs):
print(f.result())
if __name__ == '__main__':
run()
这段代码运行后会卡在 for f in as_completed(fs): 这一行,有的平台会抛出异常 TypeError: cannot serialize '_io.BufferedReader' object,有的则什么都不显示,这是因为 pymysql 提供的 Connection 对象是不可序列化的,因此多为多进程间的参数传递会产生异常。
那么,如果让这里的 MySqlDatabase 实例支持在多进程间传递呢?
解决方案
Python 提供了 __getstate__ 和 __setstate__ 方法以支持类进一步控制其实例的封存过程,这会使的实例可以被 pickle 序列化,正确实现这两个方法,实例在多进程间就可以正常传递了。
以上面的问题为例,更改 MySqlDatabase 实现如下:
class MySqlDatabase(object):
...
def __getstate__(self):
state = self.__dict__.copy()
# 移除不可序列化的属性
state.pop('conn')
return state
def __setstate__(self, state):
self.__dict__.update(state)
# 重新绑定移除的属性
self.conn = self.connect()
更新后,再次运行,就会得到预期的结果了。
扩展
- 如果类定义了
__getstate__(),它就会被调用,其返回的对象是被当做实例内容来封存的,否则封存的是实例的__dict__ - 当解封时,如果类定义了
__setstate__(),就会在已解封状态下调用它。此时不要求实例的state对象必须是dict。没有定义此方法的话,先前封存的state对象必须是dict,且该dict内容会在解封时赋给新实例的__dict__ - 该方法同样适用于
copy.copy以提供新的拷贝对象
控制 Python 类的序列化过程的更多相关文章
- 编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程
建议56:使用继承ISerializable接口更灵活地控制序列化过程 接口ISerializable的意义在于,如果特性Serializable,以及与其像配套的OnDeserializedAttr ...
- 【转】编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程
建议56:使用继承ISerializable接口更灵活地控制序列化过程 接口ISerializable的意义在于,如果特性Serializable,以及与其像配套的OnDeserializedAttr ...
- 【python】-- 类的实例化过程、特征、共有属性和私有属性
实例化过程 1.类的定义和语法 class dog(object): #用class定义类 "dog class" #对类的说明 def __init__(self,name): ...
- python原类、类的创建过程与方法
今天为大家介绍一下python中与class 相关的知识-- 获取对象的类名 python是一门面向对象的语言,对于一切接对象的python来说,咱们有必要深入的学习与了解一些知识 首先大家都知道,要 ...
- 细说python类3——类的创建过程
细说python类3——类的创建过程 https://blog.csdn.net/u010576100/article/details/50595143 2016年01月27日 18:37:24 u0 ...
- Python 之 Json序列化嵌套类
想要用python自已手动序列化嵌套类,就要明白两个问题: 1.Json是什么? 2.Json支持什么类型? 答案显而易见 Json就是嵌套对象 Json在python中支持列表,字典(当然也支持in ...
- 第8.8节 Python使用__new__方法和构造方法__init__完成类实例化的过程详解
第8.8节 Python使用__new__方法和构造方法__init__完成类实例化的过程详解 前面章节介绍了Python类中的__new__方法和构造方法__init__,并通过实例分析了二者之间关 ...
- python类:magic魔术方法
http://blog.csdn.net/pipisorry/article/details/50708812 魔术方法是面向对象Python语言中的一切.它们是你可以自定义并添加"魔法&q ...
- (转)python类:magic魔术方法
原文:https://blog.csdn.net/pipisorry/article/details/50708812 版权声明:本文为博主皮皮http://blog.csdn.net/pipisor ...
随机推荐
- VS2013中using System.Windows.Forms;引用不成功
命名空间"System"中不存在类型或命名空间名称"Windows" 项目右侧--解决资源管理器---引用---右键--添加引用---在.NET下拉框找---找 ...
- [loj3330]猜数游戏
如果两个数$a_{x}$和$a_{y}$,$\exists 0<i,a_{x}^{i}\equiv a_{y}(mod\ p^{k})$,就建一条$x$到$y$的有向边,再对这张图强连通分量缩点 ...
- [nowcoder5669J]Jumping on the Graph
考虑枚举$k$并求出$f(k)=\sum_{i=1}^{n}\limits\sum_{j=i+1}^{n}\limits [D(i,j)\le k]$,那么答案就是$\sum_{i=1}^{1e9}( ...
- SSM整合小项目
1.文件目录结构 2.MyBatis配置 创建数据库环境 CREATE DATABASE `ssmbuild`; USE `ssmbuild`; DROP TABLE IF EXISTS `books ...
- 第三方登陆-qq互联
看到很多网站都有第三方登陆,使用业余时间自己也要实现一个第三方登陆的功能: 1.登陆qq互联的网站:https://connect.qq.com/index.html 2.点击头像进行资料申请 --- ...
- 详解Threejs中的光源对象
光源的分类 AmbientLight(环境光),PointLight(点光源),SpotLight(聚光源) 和 DirectionalLight(平行光)是基础光源 HemisphereLight( ...
- CF1004D Sonya and Matrix
不要想当然. 考虑到我们一定有存在个数为\(4\)的倍数的数. 否则第一个不是的数即为\(x\). 那么我们设\(b\)为所有的数的最大值. 那么显然有\(|n - x| + |m - y| = b\ ...
- 贪心/构造/DP 杂题选做
本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...
- CF1610F F. Mashtali: a Space Oddysey
我们首先发现有如下性质: 我们不妨先随机定向边,那么我们发现无论我们如何翻转边. 都会对其两端的点,造成 \(2 / 4\) 的影响,所以我们发现如果一个点其和他相连的所有边权和为偶数,则我们不能调整 ...
- Codeforces 917C - Pollywog(状压 dp+矩阵优化)
UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊( Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1C,不过还是被我想出来了 u1 ...