Python3.6中向manager.Namespace添加manager.Queue触发TypeError问题
解决Python 3.6中manager.Queue赋值给manager.Namespace的TypeError问题
我碰到过这个问题,在Python 3.6里确实存在这个兼容性bug——当你尝试把manager.Queue()返回的代理对象赋值给manager.Namespace的属性时,内部的AutoProxy函数不识别manager_owned参数,导致抛出TypeError。下面给你几个可行的解决方案:
方案1:用manager.dict()替代Namespace存储队列
Namespace在处理代理对象时有局限,但manager.dict()可以完美支持存储代理类型的对象,比如队列:
from multiprocessing import Manager manager = Manager() shared_dict = manager.dict() shared_dict['my_queue'] = manager.Queue() # 之后在其他进程里就可以通过shared_dict['my_queue']访问这个队列了
方案2:自定义共享对象类(更灵活)
如果需要更结构化的共享数据,可以通过BaseManager注册自己的类,把队列封装进去:
from multiprocessing.managers import BaseManager class SharedData: def __init__(self): self.queue = None def get_shared_data(): return SharedData() # 注册自定义类 BaseManager.register('SharedData', get_shared_data) manager = BaseManager() manager.start() shared_data = manager.SharedData() shared_data.queue = manager.Queue() # 这样赋值就不会有问题了
方案3:升级Python版本到3.7+
这个AutoProxy的参数问题是Python 3.6的已知bug,在Python 3.7及以后的版本中已经被修复了。如果环境允许,升级版本是最直接的解决方式。
至于你提到的直接赋值multiprocessing.Queue()会触发RuntimeError,原因是原生的multiprocessing.Queue依赖于进程内的管道和锁,它不能被序列化(pickle)。而manager.Queue()返回的是一个代理对象,这个代理通过和manager进程通信来操作实际的队列,不需要序列化整个队列对象,所以只能用manager创建的队列才能在进程间共享。
内容的提问来源于stack exchange,提问作者leoschet
相关产品推荐
相关产品推荐

