2012-06-01 5 views
10

私はIPythonの並列ツールを試してみるのに問題があります。それが必要としてipythonとのPythonネームスペースの問題

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]:その後、次のコードは正常に動作

ipcluster start -n 3 

:私は私のpythonエンジンを起動します。 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 

をしてみてください次:

[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 

Iドン:

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

私は各エンジンからエラーが出ますそれを取得...私は別のファイルに関数を配置し、それをインポートすることはできませんなぜですか?

答えて

16

クイック答え:あなたはそれがエンジンのグローバル名前空間にアクセスできるようにしたい場合は、[1] IPython.parallel.utilから@interactiveであなたの関数を飾る:

 
from IPython.parallel.util import interactive 
f = interactive(lambda x: a+b+x) 
ack = dview.apply(f, x) 

を実際の説明:

IPythonのユーザーの名前空間があります本質的にモジュール__main__。これは、execute('a = 5')を実行したときにコードが実行される場所です。

あなたが対話的に関数を定義した場合、そのモジュールも__main__です:

エンジンが機能をunserializes
 
lam = lambda x: a+b+x 
lam.__module__ 
'__main__' 

、それは機能のモジュールのための適切なグローバル名前空間にそう、そうな機能がで__main__で定義されていますあなたのクライアントはエンジンの__main__にも定義されており、したがってaにアクセスできます。

ファイルに入れて、それをインポートしたら、その機能はもはや__main__に添付されているが、モジュールdop

 
from dop import dop 
dop.__module__ 
'dop' 

従来、そのモジュールで定義されたすべての関数(ラムダが含まれています)がありますこの値はエンジンで解凍されると、グローバル名前空間はdopモジュールではなく__main__ではないため、 'a'にはアクセスできません。

この理由から、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はDOPモジュールから「」使用し、idopは、あなたのエンジンの名前空間から「」を使用します。

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

[1]:IPythonで> = 0.13(今後のリリース)、ここで、それが常にべき@interactiveは、またfrom IPython.parallel import interactiveとして利用できる2つの違いは、適用に渡す機能を@interactiveに包まれていることですなっている。

関連する問題