快速回答:与装饰你的功能@interactive
从IPython.parallel.util
[1]如果你希望它有机会获得发动机的全局命名空间:
从IPython.parallel.util导入交互式
f =交互式(lambda x:a + b + x)
ack = dview.apply(f,x)
实际说明:
IPython用户名称空间本质上是模块__main__
。当您执行此操作时,将在此处运行代码execute('a = 5')
。
如果以交互方式定义函数,则其模块也是__main__
:
lam = lambda x:a + b + x
lam .__ module__
'__主要__'
当引擎反序列化一个函数时,它会在该函数模块的相应全局命名空间中进行反序列化,因此__main__
,您在客户端中定义的函数也在__main__
引擎上定义,因此可以访问a
。
将其放入文件并导入后,这些功能将不再附加到__main__
,而是模块dop
:
从dop导入dop
dop .__ module__
'dop'
该模块中常规定义的所有函数(包括lambda)都将具有该值,因此在引擎上解压缩它们时,其全局名称空间将是该dop
模块的全局名称空间, 而不是 该模块的全局名称空间__main__
,因此您的“ a”不可访问。
出于这个原因,IPython提供了一个简单的@interactive
装饰器__main__
,无论该函数实际定义在哪里,它都会像在中定义的那样对任何函数进行解包。
有关差异的示例,请执行以下操作dop.py
:
从IPython.parallel导入客户端
从IPython.parallel.util导入交互式
a = 1
def dop(x):
rc = Client()
dview = rc [:]
dview ['a'] = 5
f =λx:a + x
返回dview.apply_sync(f,x)
def idop(x):
rc = Client()
dview = rc [:]
dview ['a'] = 5
f =交互式(lambda x:a + x)
返回dview.apply_sync(f,x)
现在,dop
将在dop模块中idop
使用“ a”,并在引擎名称空间中使用“ a”。两者之间的唯一区别是传递给apply的函数包装在@interactive
:
从dop导入dop,idop
打印dop(5)#6
打印idop(5)#10
[1]:在IPython> = 0.13(即将发行的版本)中,@interactive
它也from IPython.parallel import interactive
应该作为,应该总是存在。