问题

有的类是不支持在多进程间传递的,如果非要这么做,可能会引发奇怪的现象。比如下面这段代码:

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 类的序列化过程的更多相关文章

  1. 编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程

    建议56:使用继承ISerializable接口更灵活地控制序列化过程 接口ISerializable的意义在于,如果特性Serializable,以及与其像配套的OnDeserializedAttr ...

  2. 【转】编写高质量代码改善C#程序的157个建议——建议56:使用继承ISerializable接口更灵活地控制序列化过程

    建议56:使用继承ISerializable接口更灵活地控制序列化过程 接口ISerializable的意义在于,如果特性Serializable,以及与其像配套的OnDeserializedAttr ...

  3. 【python】-- 类的实例化过程、特征、共有属性和私有属性

    实例化过程 1.类的定义和语法 class dog(object): #用class定义类 "dog class" #对类的说明 def __init__(self,name): ...

  4. python原类、类的创建过程与方法

    今天为大家介绍一下python中与class 相关的知识-- 获取对象的类名 python是一门面向对象的语言,对于一切接对象的python来说,咱们有必要深入的学习与了解一些知识 首先大家都知道,要 ...

  5. 细说python类3——类的创建过程

    细说python类3——类的创建过程 https://blog.csdn.net/u010576100/article/details/50595143 2016年01月27日 18:37:24 u0 ...

  6. Python 之 Json序列化嵌套类

    想要用python自已手动序列化嵌套类,就要明白两个问题: 1.Json是什么? 2.Json支持什么类型? 答案显而易见 Json就是嵌套对象 Json在python中支持列表,字典(当然也支持in ...

  7. 第8.8节 Python使用__new__方法和构造方法__init__完成类实例化的过程详解

    第8.8节 Python使用__new__方法和构造方法__init__完成类实例化的过程详解 前面章节介绍了Python类中的__new__方法和构造方法__init__,并通过实例分析了二者之间关 ...

  8. python类:magic魔术方法

    http://blog.csdn.net/pipisorry/article/details/50708812 魔术方法是面向对象Python语言中的一切.它们是你可以自定义并添加"魔法&q ...

  9. (转)python类:magic魔术方法

    原文:https://blog.csdn.net/pipisorry/article/details/50708812 版权声明:本文为博主皮皮http://blog.csdn.net/pipisor ...

随机推荐

  1. python实现图像二值化

    1.什么是图像二值化 彩色图像: 有blue,green,red三个通道,取值范围均为0-255 灰度图:只有一个通道0-255,所以一共有256种颜色 二值图像:只有两种颜色,黑色和白色,二值化就是 ...

  2. SQL中单引号和双引号

    比如说: String sql = "select * from clients where logname='" + name + "'and password='&q ...

  3. Tomcat无法启动解决办法

    [2014-04-12 12:34:39] [error] [ 1080] 操作系统找不到已输入的环境选项. [2014-04-12 12:34:39] [error] [ 1052] Failed ...

  4. Java安全之基于Tomcat的Filter型内存马

    Java安全之基于Tomcat的Filter型内存马 写在前面 现在来说,内存马已经是一种很常见的攻击手法了,基本红队项目中对于入口点都是选择打入内存马.而对于内存马的支持也是五花八门,甚至各大公司都 ...

  5. [hdu7081]Pty loves book

    建立ac自动机,令$S_{x}$为以根到$x$的路径所构成的字符串以及$L_{x}=|S_{x}|,W_{x}=\sum_{1\le i\le m,t_{i}为S_{x}的后缀}w_{i}$,那么不难 ...

  6. [hdu7022]Jsljgame

    先考虑$x=y$的情况,此时即是一个平等博弈,因此考虑$sg$函数 具体的,有$sg(n)=\begin{cases}0&(n=0)\\mex(\{sg(n-i)\mid 1\le i\le ...

  7. SpringCloud微服务实战——搭建企业级开发框架(二十三):Gateway+OAuth2+JWT实现微服务统一认证授权

      OAuth2是一个关于授权的开放标准,核心思路是通过各类认证手段(具体什么手段OAuth2不关心)认证用户身份,并颁发token(令牌),使得第三方应用可以使用该token(令牌)在限定时间.限定 ...

  8. maven项目打包不带版本号的操作

  9. Atcoder Regular Contest 123 题解

    u1s1 我是真的不知道为什么现场这么多人切了 D,感觉 D 对思维要求显然要高于其他 300+ 人切掉的 D 吧(也有可能是 Atc 用户整体水平提升了?) A 开 幕 雷 击(这题似乎 wjz 交 ...

  10. 【百奥云GS专栏】全基因组选择之工具篇

    目录 1. 免费开源包/库 1.1 R包 1.2 Python库 2. 成熟软件 3. WEB/GUI工具 前面我们已经介绍了基因组选择的各类模型,今天主要来了解一下做GS有哪些可用的软件和工具.基因 ...