2017-12-17 20 views
1

'caller.py'에서 호출 된 'timex.py'에 정의 된 작은 도우미 함수를 호출하려고합니다.이 함수는 차례대로 "Python의 호출자"인 IPython-console에서 호출해야합니다. "% run caller.py ".가져온 함수 내에서 IPython의 마술에 호출자의 네임 스페이스를 사용 가능하게 만드는 방법은 무엇입니까?

"NameError : name 'pickle'이 (가) 정의되지 않았습니다.


# Then run from IPython-console: 

>>>%run caller.py 
time expression: pickle.dumps(packet, protocol=-1) 
NameError: name 'pickle' is not defined 


# caller.py 

import pickle 
from timex import time_expression 

packet = [*range(10**2)] 
time_expression("pickle.dumps(packet, protocol=-1)") 
# timex.py 

from IPython import get_ipython 

def time_expression(exp: str):  
    print(f"time expression: {exp}", flush=True) 
    return get_ipython().magic(f"timeit {exp}") 

은 분명히 ipython의 timeit - 마법의 네임 스페이스는 caller.py-전역이 포함되어 있지 않습니다. time_expression의 인수로 globals()를 전달하고 time_expression 내에서 전역 변수를 업데이트하는 것은 도움이되지 않았고 인수가 트릭을 수행하지 않았으므로 get_ipython()을 전달했습니다.

작동시키기위한 방법이 있습니까?

time_expression을 caller.py에 정의하고 "ipython caller.py"를 사용하여 Terminal에서 호출하면 작동하지만, 라이브러리에 넣고 필요한 곳에 가져 오는 것이 좋습니다.

(파이썬 3.6.3, IPython 6.2.1)

답변

0

좋아 내가 운이 보인다. 여기서 힌트를 찾았습니다. link, 쉘에 'user_ns'인수가 있습니다. 이 user_ns-dictionary를 호출자의 지역민으로 업데이트하면 IPython 콘솔에서 % run caller.py를 실행하여 caller.py에서 가져 오기 작업을 수행 할 수있는 솔루션이되었습니다.

조금 해킹되어서 더러운 느낌이 들었습니다. 더 우아한 방법이 있습니까?

import sys 
from IPython import get_ipython 

def time_expression(exp: str): 
    """""" 
    ipy = get_ipython() 
    ipy.__dict__['user_ns'].update(sys._getframe(1).f_locals) 
    print(f"time expression: {exp}", flush=True) 
    return ipy.magic(f"timeit {exp}")