2012-06-01 2 views
10

IPython 병렬 도구를 실험하고 있는데 문제가 있습니다. 다음 코드는 잘 실행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 

을 시도 다음

[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

빠른 대답 :

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

실제 설명 :

IPython 사용자 공간입니다 IPython.parallel.util에서 @interactive 당신이 엔진의 글로벌 네임 스페이스에 액세스 할 수 있도록하려면 [1]로 기능을 장식 본질적으로 모듈 __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 (곧 출시)에는 @interactivefrom IPython.parallel import interactive로서 사용할 곳에 항상한다 둘 사이의 유일한 차이는 적용되는 전달 함수가 @interactive 래핑되어있다 있었어.

관련 문제