Python 多处理管理器删减了一些方法
Python Multiprocessing manager prunes some methods
我发现 Manager
在实践中很少适用于大多数自定义对象,因为它删除了一些 class 成员。看一个例子:
from multiprocessing import Manager
from scipy.interpolate import CubicSpline
cs_pure = CubicSpline([1,2,3], [1,2,3])
test_pure = cs_pure(1)
m = Manager()
m.register('CubicSpline', CubicSpline)
cs_m = m.CubicSpline([1,2,3], [1,2,3])
test_m = cs_m(1)
这将引发异常:
TypeError: 'AutoProxy[CubicSpline]' object is not callable
令人惊讶的是,大多数其他方法(例如 integrate
、differentiate
)都按预期工作。但是 __call__
方法不存在。
是否有解决方法?
你是说 test_m = cs_m(1)
吗?
首先,根据我的经验,您必须在管理器服务器启动之前向管理器的 class 注册托管 class:
from multiprocessing.managers import SyncManager
from multiprocessing import Manager
from scipy.interpolate import CubicSpline
SyncManager.register('CubicSpline', CubicSpline)
m = Manager()
...
所以我不确定你是怎么做到的。如果您不需要使用 SyncManager
(例如 dict
)实现的所有其他已注册托管 classes,创建自己的管理器 class 也更为常见。我将在下面的代码中演示这一点(使用或不使用此技术,如您所愿)。
我认为问题在于当您没有定义自己的代理 class 时,__call__
方法不会在为您生成的代理 class 中自动生成。与其定义自己的代理 class,我认为更简单的解决方案是将 CubicSpline
class 子 class 并添加一个额外的方法,例如 evaluate_polynomial
只需调用 superclass __call__
方法:
from multiprocessing.managers import BaseManager
from scipy.interpolate import CubicSpline
class CubicSplineManager(BaseManager):
pass
class MyCubicSpline(CubicSpline):
def evaluate_polynomial(self, *args, **kwargs):
return self.__call__(*args, **kwargs)
if __name__ == '__main__':
cs_pure = CubicSpline([1,2,3], [1,2,3])
test_pure = cs_pure(1)
print(test_pure)
CubicSplineManager.register('CubicSpline', MyCubicSpline)
m = CubicSplineManager()
m.start() # We must explicitly start the server
cs_m = m.CubicSpline([1,2,3], [1,2,3])
test_m = cs_m.evaluate_polynomial(1)
print(test_m)
打印:
1.0
1.0
我发现 Manager
在实践中很少适用于大多数自定义对象,因为它删除了一些 class 成员。看一个例子:
from multiprocessing import Manager
from scipy.interpolate import CubicSpline
cs_pure = CubicSpline([1,2,3], [1,2,3])
test_pure = cs_pure(1)
m = Manager()
m.register('CubicSpline', CubicSpline)
cs_m = m.CubicSpline([1,2,3], [1,2,3])
test_m = cs_m(1)
这将引发异常:
TypeError: 'AutoProxy[CubicSpline]' object is not callable
令人惊讶的是,大多数其他方法(例如 integrate
、differentiate
)都按预期工作。但是 __call__
方法不存在。
是否有解决方法?
你是说 test_m = cs_m(1)
吗?
首先,根据我的经验,您必须在管理器服务器启动之前向管理器的 class 注册托管 class:
from multiprocessing.managers import SyncManager
from multiprocessing import Manager
from scipy.interpolate import CubicSpline
SyncManager.register('CubicSpline', CubicSpline)
m = Manager()
...
所以我不确定你是怎么做到的。如果您不需要使用 SyncManager
(例如 dict
)实现的所有其他已注册托管 classes,创建自己的管理器 class 也更为常见。我将在下面的代码中演示这一点(使用或不使用此技术,如您所愿)。
我认为问题在于当您没有定义自己的代理 class 时,__call__
方法不会在为您生成的代理 class 中自动生成。与其定义自己的代理 class,我认为更简单的解决方案是将 CubicSpline
class 子 class 并添加一个额外的方法,例如 evaluate_polynomial
只需调用 superclass __call__
方法:
from multiprocessing.managers import BaseManager
from scipy.interpolate import CubicSpline
class CubicSplineManager(BaseManager):
pass
class MyCubicSpline(CubicSpline):
def evaluate_polynomial(self, *args, **kwargs):
return self.__call__(*args, **kwargs)
if __name__ == '__main__':
cs_pure = CubicSpline([1,2,3], [1,2,3])
test_pure = cs_pure(1)
print(test_pure)
CubicSplineManager.register('CubicSpline', MyCubicSpline)
m = CubicSplineManager()
m.start() # We must explicitly start the server
cs_m = m.CubicSpline([1,2,3], [1,2,3])
test_m = cs_m.evaluate_polynomial(1)
print(test_m)
打印:
1.0
1.0