4

我发现了一堆关于类似问题的问题(例如这个,在处理 iPython.Parallel 时,酸洗闭包的问题似乎无处不在,但我无法在任何地方解决这个特定问题。所以我的问题如下:

我想为使用 ipclusterf( a, b )的多个值的函数求解零。本身就是一个复杂的函数。让我们用一个愚蠢的例子bf

import scipy.optimize

def f(a,b):
     return (a+b)**2 + numpy.sin(a*b)

bs = range( 20 )

for b in bs:
     g = lambda a : f(a,b)
     root = scipy.optimize.fsolve( g, 0.0 )
     print root

好吧,这就是我正在做的事情的一般概念。问题是,如果我尝试创建一个返回根的函数,它将必须创建一个闭包并将其传递给scipy.optimize.fsolve(我认为)。例如,我尝试过

 def root( b ):
      g = lambda a : f( a, b )
      return scipy.optimize.fsolve( g, 0.0 )

但是如果你使用iPython.Parallel'smap它将无法腌制闭包。我想不出任何办法,你可以吗?


我想重现错误的最小示例是

import numpy
import scipy.optimize

from IPython.parallel import Client

def f( a,b):
    return (a+b)**2+numpy.cos(a*b)

def h( a,b=1.0):
    return (a+b)**2+numpy.cos(a*b)

def root_h( a ):#argument just for mapping, not used
    return scipy.optimize.fsolve( h, 0.0 )

def root(b):
    g = lambda a : f(a,b)
    return scipy.optimize.fsolve( g, 0.0 )

if __name__=='__main__':

    #first normally, this works
    print root( 1.0 )
    print root( 2.0 )

    #now parallely, doesn't work
    c = Client()
    dview = c[:]
    with dview.sync_imports():
        import numpy
        import scipy.optimize

    #this works
    dview.push({'h':h})
    res = dview.map( root_h, [1.0,2.0] )

    for i in res:
        print i

    #this doesn't
    dview.push({'f':f})
    res = dview.map( root, [1.0,2.0] )

    for i in res:
        print i

ValueError: Sorry, cannot pickle code objects with closures如果有人能想到解决方法,它会为我抛出错误......

干杯,谢谢大家,所以肯定会帮助很多人:)。

4

1 回答 1

3

如果避免在 root(b) 中创建闭包怎么办?

我会尝试

def root(b):
    g = lambda a, b=b : f(a,b)
    return scipy.optimize.fsolve( g, 0.0 )

对于您的示例,它给出了预期的结果,而不是 Pickle 错误。

说明:我相信发生闭包是因为您的 lambda 函数正在调用 f(a,b) 其中 b 是来自外部(封闭)命名空间的变量。我显式地提交该变量(lambda;s 可以有多个参数甚至关键字参数)它不再是一个闭包。

于 2013-10-22T06:12:19.357 回答