Python 将sympy lambda传递给multiprocessing.Pool.map
我想并行执行一个sympy lambda函数。 我不知道:Python 将sympy lambda传递给multiprocessing.Pool.map,python,multiprocessing,sympy,Python,Multiprocessing,Sympy,我想并行执行一个sympy lambda函数。 我不知道: 尽管它是一个lambda函数,但为什么它并行工作 为什么当我尝试在没有池的情况下执行时它停止工作 为什么在lambdify 显然,降价预处理器需要在代码上方有一行文本,所以这是代码: from multiprocessing import Pool import sympy from sympy.abc import x def f(m): return m.lambdify()(1) class Mult():
- 尽管它是一个lambda函数,但为什么它并行工作
- 为什么当我尝试在没有池的情况下执行时它停止工作
- 为什么在
lambdify
from multiprocessing import Pool
import sympy
from sympy.abc import x
def f(m):
return m.lambdify()(1)
class Mult():
def lambdify(self):
# return sympy.lambdify(x, 2*x, 'numpy')
self._lambdify = sympy.lambdify(x, 2 * x, 'numpy')
return self._lambdify
if __name__ == '__main__':
with Pool() as pool:
m = Mult()
print(pool.map(f, [m]))
print(pool.map(f, [m]))
print(f(m))
print(pool.map(f, [m]))
它打印:
[2]
[2]
2
PicklingError: Can't pickle <function <lambda> at 0x000000000DF0D048>: attribute lookup <lambda> on numpy failed
我只在Windows上进行了测试,它的工作原理与“numexpr”而不是“numpy”完全相同。对象
Mult
在创建时没有字段。因此,可以使用库存pickle
库对其进行酸洗。然后,在调用lambdify
时,向包含lambda
表达式的对象添加一个\u lambdify
属性,该表达式不能被pickle。这会导致map
功能出现故障
这解释了为什么在调用lambdify
之前可以pickle对象并使用Pool.map
以及为什么调用后失败。
当您取消注释
lambdify
中的行时,您不会将属性添加到类中,调用lambdify
后,Mult
对象仍然可以被pickle,尽管我还没有完全探讨过这一点,我只想记录在案,当使用loky而不是多处理时,相同的示例可以很好地工作:
从loky导入获取可重用的执行器
进口交响乐
从sympy.abc导入x
def f(m):
返回m.lambdify()(1)
类Mult():
def lambdify(自身):
#返回sympy.lambdify(x,2*x,'numpy')
self.\u lambdify=sympy.lambdify(x,2*x,'numpy')
返回自我
executor=获取可重用的执行器()
m=Mult()
打印('pool.map(f[m]),列表(executor.map(f[m]))
打印('pool.map(f[m]),列表(executor.map(f[m]))
打印('f(m'),f(m))
打印('pool.map(f[m]),列表(executor.map(f[m]))
有输出
pool.map(f, [m]) [2]
pool.map(f, [m]) [2]
f(m) 2
pool.map(f, [m]) [2]
您不能使用
multiprocessing.Pool.map()
跨进程调用活动对象实例的方法,除非您特意解释了目标子进程如何在其一侧重建活动对象。例如,检查。@zwer当然可以,但它没有解释第2点和第3点。它听起来好像解释了一切。您是否有“向包含lambda表达式的对象添加_lambdify属性,该表达式不能被pickle”的引用?解释为什么lambda表达式不能被pickle。请注意,显然,可以序列化来自symphy.lambdify
的结果。我的坏,dill
也无法picklesymphy
对象。哦,对不起,我不明白你第一次说的是什么。你完全正确。改变的是我尝试对一个包含lambda的对象进行pickle处理。谢谢!的确,洛基很了不起。的界面也非常有用。
pool.map(f, [m]) [2]
pool.map(f, [m]) [2]
f(m) 2
pool.map(f, [m]) [2]