Python 将sympy lambda传递给multiprocessing.Pool.map

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():

我想并行执行一个sympy lambda函数。 我不知道:

  • 尽管它是一个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
也无法pickle
symphy
对象。哦,对不起,我不明白你第一次说的是什么。你完全正确。改变的是我尝试对一个包含lambda的对象进行pickle处理。谢谢!的确,洛基很了不起。的界面也非常有用。
pool.map(f, [m]) [2]
pool.map(f, [m]) [2]
f(m) 2
pool.map(f, [m]) [2]