10

IPython並列ツールの実験を始めていますが、問題があります。私はPythonエンジンを次のように起動します:

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

わからない...関数を別のファイルに入れてインポ​​ートできないのはなぜですか?

4

1 に答える 1

16

@interactiveクイックアンサー:エンジンのグローバル名前空間にアクセスできるようにする場合は、関数をfrom IPython.parallel.util[1]で装飾します。

IPython.parallel.utilからインポートインタラクティブ
f =インタラクティブ(ラムダx:a + b + x)
ack = dview.apply(f、x)

実際の説明:

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

関数をインタラクティブに定義する場合、そのモジュールも__main__次のようになります。

lam =ラムダx:a + b + x
lam .__ module__
'__主要__'

エンジンが関数をアンシリアル化すると、関数のモジュールの適切なグローバル名前空間でアンシリアル化されるため__main__、クライアントで定義された関数も__main__エンジンで定義され、にアクセスできますa

ファイルに入れてインポ​​ートすると、関数はにアタッチされなくなり__main__ますが、モジュールは次のようになりますdop

dopからimportdop
dop .__ module__
'dop'

そのモジュールで従来定義されているすべての関数(ラムダを含む)はこの値を持つため、エンジンでアンパックされると、グローバル名前空間は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 =インタラクティブ(ラムダx:a + x)
    dview.apply_sync(f、x)を返します

ここでdop、dopモジュールのidop「a」を使用し、エンジンの名前空間の「a」を使用します。2つの違いは、applyに渡される関数が次のようにラップされていることだけです@interactive

dopからimportdop、idop
print dop(5)#6
print idop(5)#10

[1]:IPython> = 0.13(今後のリリース)では、@interactiveとしても利用できますがfrom IPython.parallel import interactive、常にそうあるべきでした。

于 2012-06-02T02:40:16.020 に答える