跨RPyC进程传递Python枚举实例致KeyError,是否仅能用value/name?
解决跨RPyC进程传递枚举实例导致的KeyError问题
你完全说对了!问题的核心就是跨进程创建的枚举实例是彼此独立的对象——哪怕它们的name和value完全一致,通过RPyC传递后,PC2收到的枚举实例和它本地定义的config.CameraList.EYE根本不是同一个东西,自然没法匹配字典里的键,触发KeyError是必然的。
为什么会这样?
RPyC在跨进程传递非基本类型对象时,会做序列化/反序列化处理。枚举实例看起来像“值类型”,但本质是Python对象,跨进程传递后会被重新实例化,导致它的身份标识(比如id())和PC2本地的枚举实例完全不同。而字典的键匹配依赖对象的哈希值和身份一致性,直接传枚举实例肯定会不匹配。
两种可行的解决方案
1. 传递枚举的value属性
这是最直接的方案,因为value是整数(0、1、2这种基本类型),跨进程传递不会有任何序列化问题。PC2收到后可以直接用这个值找字典键,或者转成本地枚举实例再用:
# PC1端调用RPyC方法时 conn.root.get_image(config.CameraList.EYE.value) # PC2端处理方法 def get_image(cam_value): # 方式一:直接用value作为键访问字典 cam_config = config.cameras.get(cam_value) # 方式二:先转成本地枚举实例,再访问字典(可读性更好) cam_enum = config.CameraList(cam_value) cam_config = config.cameras.get(cam_enum)
2. 传递枚举的name属性
用枚举的名称字符串(比如"EYE")传递也可以,同样属于基本类型,不会有序列化问题,而且语义更清晰:
# PC1端调用RPyC方法时 conn.root.get_image(config.CameraList.EYE.name) # PC2端处理方法 def get_image(cam_name): # 通过name转成本地枚举实例 cam_enum = config.CameraList[cam_name] cam_config = config.cameras.get(cam_enum)
小建议
如果你的字典键是枚举实例,更推荐在PC2端把收到的参数转成本地枚举实例后再访问字典——这样代码的可读性更强,也能避免后续如果枚举值调整可能带来的潜在问题。
内容的提问来源于stack exchange,提问作者juerg
相关产品推荐
相关产品推荐

