1

我想使用 IPython.parallel 并行化一个函数,当我在 IPython shell 中定义它时,它可以完美地工作:

Type:       function
Base Class: <type 'function'>
String Form:<function gradient at 0x3ae0398>
Namespace:  Interactive
File:       /root/<ipython-input-30-cf7eabdfef84>
Definition: gradient(w) 
Source:
def gradient(w):
    s = (1.0 + exp(y * (X * w)))**-1
    return C*X.T*((1 - s) * y)

rc = Client() 
rc[:].apply_sync(gradient, w)
...

但是,当我在模块中定义它并使用导入时:

Type:       function
Base Class: <type 'function'>
String Form:<function gradient at 0x3933d70>
Namespace:  Interactive
File:       /root/mv.py
Definition: mv.gradient(w)
Source:
def gradient(w):
    s = (1.0 + exp(y * (X * w)))**-1
    return C*X.T*((1 - s) * y)

import mv 
rc = Client()
rc[:].apply_sync(mv.gradient, w)

CompositeError: one or more exceptions from call to method: gradient
[0:apply]: NameError: global name 'y' is not defined
[1:apply]: NameError: global name 'y' is not define

此外,它在运行 Python 2.7.2/IPython 0.12 的本地系统上运行良好,而使用最新的 Starcluster Ubuntu AMI 在 Python 2.7.2+/IPython 0.12 上崩溃。

这里发生了什么?

更新:我从 github 安装了 IPython 0.13.dev 版本,现在它可以工作了。

4

1 回答 1

3

不同之处在于模块全局变量。在模块中定义函数时,全局命名空间就是模块的命名空间(即mv.y)。例如,当该模块是__main__交互式定义的函数时,全局命名空间是引擎上的 user_ns,并受execute("y=5").

IPython 提供了一个装饰器,如果你想在模块中定义函数,这些函数应该表现得好像它们是交互式定义的(可以作为全局变量访问用户命名空间):

# 我的模组

从 IPython.parallel.util 导入交互式

@交互的
定义 by_a(b):
    """a 乘 b"
    返回 a*b

并且以交互方式,您可以执行以下操作:

从 mymod 导入 by_a

e0 = rc[0]
e0.execute("a=5")
打印 e0.apply_sync(by_a, 10) # 50
e0.execute("a=10")
打印 e0.apply_sync(by_a, 10) # 100
于 2012-05-05T18:54:22.517 回答