Python多进程自定义管理器关联对象调用报错求助
解决多进程中自定义类属性访问的AttributeError问题
问题原因
你遇到的AttributeError: 'AutoProxy[BusObject]' object has no attribute 'inputs',本质是因为:
- 通过Manager创建的
BusObject是代理对象(AutoProxy),它只暴露注册类中明确可被跨进程访问的属性和方法 - 原
BusObject.__init__中直接创建的IOObject是manager进程内的本地对象,不是代理对象,无法被外部进程通过BusObject的代理访问到 - 即便注册了
IOObject,如果不修改BusObject的创建逻辑,内部的inputs/outputs依然是本地实例,不会被自动转为代理
解决方案
需要让BusObject内部的IOObject实例也通过Manager创建为代理对象,具体步骤如下:
1. 同时注册两个自定义类
确保IOObject和BusObject都注册到自定义Manager中
2. 修改BusObject的初始化逻辑
不要在BusObject内部直接实例化IOObject,而是通过Manager提供的接口创建代理实例。以下是两种可行实现方式:
方式一:在BusObject中传入Manager引用(推荐)
from multiprocessing.managers import BaseManager from typing import List class IOObject: idx: List[int] tag: List[str] def __init__(self): self.idx = [] self.tag = [] class BusObject: inputs: IOObject outputs: IOObject def __init__(self, manager): # 通过manager创建IOObject的代理实例 self.inputs = manager.IOObject() self.outputs = manager.IOObject() class CustomManager(BaseManager): pass def main(): manager = CustomManager() # 注册两个自定义类 manager.register('BusObject', BusObject) manager.register('IOObject', IOObject) manager.start() # 创建BusObject时传入manager引用 busObject = manager.BusObject(manager) # 测试跨进程属性访问 busObject.inputs.idx.append(1) print(busObject.inputs.idx) # 输出 [1] if __name__ == "__main__": main()
方式二:预先创建IOObject代理再传入BusObject
如果不想传入manager,可以在主逻辑中先创建IOObject代理,再传递给BusObject:
# 修改BusObject的__init__方法 class BusObject: inputs: IOObject outputs: IOObject def __init__(self, input_io, output_io): self.inputs = input_io self.outputs = output_io def main(): manager = CustomManager() manager.register('BusObject', BusObject) manager.register('IOObject', IOObject) manager.start() # 先创建IOObject代理实例 input_io = manager.IOObject() output_io = manager.IOObject() # 传入BusObject完成初始化 busObject = manager.BusObject(input_io, output_io)
3. 额外注意事项
- 所有需要跨进程访问的对象,必须是Manager创建的代理实例,不能是本地实例
- 自定义类的简单属性访问和方法调用会被Manager自动代理转发,复杂逻辑可能需要自定义代理处理
- 在Windows系统中,必须将启动代码放在
if __name__ == "__main__":代码块内,避免多进程导入异常
内容的提问来源于stack exchange,提问作者Viktor Katzy
相关产品推荐
相关产品推荐

