Python Multiprocessing Manager注册对象丢失__call__方法的解决方案问询
问题根因
multiprocessing.Manager默认的AutoProxy生成代理对象时,不会自动暴露类的双下划线开头的特殊方法,仅会识别普通命名的公开方法。__call__属于Python特殊魔法方法,因此没有被加入代理的可调用方法列表,才会抛出不可调用的错误,而integrate、differentiate这类普通命名的方法不受影响。
可行解决方案
方案1:注册类时手动指定要暴露的方法列表
在调用m.register()时,显式传入exposed参数,把需要用到的特殊方法和普通方法都加入列表即可,改动最小无需修改原有类实现,适合大部分场景:
from multiprocessing import Manager from scipy.interpolate import CubicSpline cs_pure = CubicSpline([1,2,3], [1,2,3]) test_pure = cs_pure(1) print(test_pure) # 输出1.0,本地对象正常运行 m = Manager() # 手动指定需要暴露的方法,包含__call__和其他需要用到的方法 exposed_methods = ['__call__', 'integrate', 'differentiate'] m.register('CubicSpline', CubicSpline, exposed=exposed_methods) cs_m = m.CubicSpline([1,2,3], [1,2,3]) test_m = cs_m(1) print(test_m) # 输出1.0,代理对象正常运行
方案2:封装自定义包装类适配代理
如果需要用到的特殊方法较多,也可以给原类套一层简单的包装,把特殊方法转为普通命名的方法调用,彻底避开代理对特殊方法的识别限制:
from multiprocessing import Manager from scipy.interpolate import CubicSpline class WrappedCubicSpline: def __init__(self, x, y): self.cs = CubicSpline(x, y) def call(self, x): return self.cs(x) def integrate(self, *args, **kwargs): return self.cs.integrate(*args, **kwargs) def differentiate(self, *args, **kwargs): return self.cs.differentiate(*args, **kwargs) m = Manager() m.register('WrappedCubicSpline', WrappedCubicSpline) cs_m = m.WrappedCubicSpline([1,2,3], [1,2,3]) test_m = cs_m.call(1) print(test_m) # 输出1.0,运行正常
内容的提问来源于stack exchange,提问作者Jeor
相关产品推荐
相关产品推荐

