与IPython的并行Python的名字空间的问题(Python name space issues

2019-06-25 02:24发布

我开始尝试与IPython的并行工具,并有一个问题。 我开始了我的蟒蛇发动机具有:

ipcluster start -n 3

然后将以下代码罚款运行:

from IPython.parallel import Client

def dop(x):
    rc = Client()
    dview = rc[:]
    dview.block=True
    dview.execute('a = 5')
    dview['b'] = 10
    ack = dview.apply(lambda x: a+b+x, x)
    return ack

ack = dop(27)
print ack

返回[42,42,42],它应。 但是,如果我打破了代码转换成不同的文件:dop.py:

from IPython.parallel import Client

def dop(x):
    rc = Client()
    dview = rc[:]
    dview.block=True
    dview.execute('a = 5')
    dview['b'] = 10
    print dview['a']
    ack = dview.apply(lambda x: a+b+x, x)
    return ack

和尝试以下操作:

from dop import dop
ack = dop(27)
print ack

我从每个引擎的错误:

[0:apply]: NameError: global name 'a' is not defined
[1:apply]: NameError: global name 'a' is not defined
[2:apply]: NameError: global name 'a' is not defined

我不明白这一点......我为什么不能把功能不同的文件,并导入了吗?

Answer 1:

快速回答:与装饰你的功能@interactiveIPython.parallel.util [1]如果你希望它有机会获得发动机的全局命名空间:

from IPython.parallel.util import interactive
f = interactive(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__'

当发动机unserializes的功能,但是这样做的对功能的模块选择合适的全局命名空间,所以在定义函数__main__在客户端中也定义__main__在发动机上,从而有机会获得a

一旦你把它放在一个文件,并将其导入,那么功能不再连接到__main__ ,但模块dop

from dop import dop
dop.__module__
'dop'

所有的功能通常在该模块中定义(包括lambda表达式)都会有这个值,所以当他们解包的引擎的全局命名空间将是对的dop模块, __main__ ,所以,您的一个不可访问。

出于这个原因,IPython中提供了一个简单@interactive就好像它是在定义的被解压缩导致任何功能装饰__main__ ,而不管该函数实际上是定义在何处。

对于差的一个例子,借此dop.py

from IPython.parallel import Client
from IPython.parallel.util import interactive

a = 1

def dop(x):
    rc = Client()
    dview = rc[:]
    dview['a'] = 5
    f = lambda x: a+x
    return dview.apply_sync(f, x)

def idop(x):
    rc = Client()
    dview = rc[:]
    dview['a'] = 5
    f = interactive(lambda x: a+x)
    return dview.apply_sync(f, x)

现在, dop将使用“A”从DOP模块,并idop将使用“A”从你的引擎命名空间。 两者之间的唯一区别是,通过应用功能被包裹在@interactive

from dop import dop, idop
print dop(5)  # 6
print idop(5) # 10

[1]:在IPython中> = 0.13(即将发布), @interactive也可作为from IPython.parallel import interactive ,它总是应该已经。



文章来源: Python name space issues with ipython parallel