如何协同IPython< - >回调()

时间:2016-10-09 16:49:36

标签: python scipy ipython coroutine

在IPython终端中,我希望main()内有一个函数 回到IPython,在那里我可以打印,设置......像往常一样,然后继续运行main()

IPython
    run main.py
    ...
    def callback( *args ):
        ...
        try:
            back_to_ipython()  # <-- how to do this ?
                In[]: print, set *args ...
                ...
        except KeyboardInterrupt:  # or IPython magic
            pass

        return  # from callback(), keep running main()

这必须在python2中运行。

(名称callback可以是anything,但我的用例是scipy.optimize - &gt;回调。 也许一些聪明的scipy人已经做到了这一点?)

<小时/> 10月11日星期二:感谢embed, 但它似乎遇到了一个错误,或者我的误解:

# http://stackoverflow.com/questions/39946052/how-to-coroutine-ipython-a-callback

import sys
from IPython import __version__
from IPython import embed  # $site/IPython/terminal/embed.py
from IPython.terminal.ipapp import load_default_config

print "versions: IPython %s  python %s" % (
        __version__, sys.version.split()[0] )

def pdict( header, adict ):
    print header
    for k, v in sorted( adict.items() ):
        print "%s\t: %s" % (k, v)

config = load_default_config()
pdict( "load_default_config:", config )

aglobal = [3]

#...............................................................................
def callback( adict ):
    # pdict( "callback:", adict )
    t = adict["t"]
    x = 3
    embed( header="callback: t %d" % t )
        # interact: print t x ...
        # ^D / EOF
    return

def aloop( *args ):
    for t in range( 3 ):
        callback( locals() )

aloop( 1, 2, 3 )  # works in "run this.py"
# but typing "aloop()" in an IPython terminal ->
# embed.py:218: UserWarning: Failed to get module unknown module
#  global_ns.get('__name__', 'unknown module')

2 个答案:

答案 0 :(得分:0)

你可以插入一个断点,这会产生类似的结果:

import pdb; pdb.set_trace()

https://docs.python.org/3.6/library/pdb.html

此处替代(iPython中的embed()功能): Step-by-step debugging with IPython

答案 1 :(得分:0)

https://stackoverflow.com/a/24827245/901925中修改答案,我添加了Ipython embedhttps://ipython.org/ipython-doc/3/api/generated/IPython.terminal.embed.html

import numpy as np
from scipy.optimize import minimize, rosen
import time
import warnings
from IPython import embed

class TookTooLong(Warning):
    pass

class MinimizeStopper(object):
    def __init__(self, max_sec=60):
        self.max_sec = max_sec
        self.start = time.time()
    def __call__(self, xk=None):
        elapsed = time.time() - self.start
        if elapsed > self.max_sec:
            embed(header='FirstTime')
            warnings.warn("Terminating optimization: time limit reached",
                          TookTooLong)
        else:
            # you might want to report other stuff here
            print("Elapsed: %.3f sec" % elapsed)

# example usage
x0 = [1.3, 0.7, 0.8, 1.9, 1.2]
res = minimize(rosen, x0, method='Nelder-Mead', callback=MinimizeStopper(1E-3))

运行如:

1251:~/mypy$ python3 stack39946052.py 
Elapsed: 0.001 sec
Python 3.5.2 (default, Jul  5 2016, 12:43:10) 
Type "copyright", "credits" or "license" for more information.

IPython 5.1.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.


FirstTime

In [1]: xk
Out[1]: array([ 1.339,  0.721,  0.824,  1.71 ,  1.236])

In [2]: elapsed
Out[2]: 0.0010917186737060547

In [3]: self.max_sec
Out[3]: 0.001

In [4]: self.max_sec=1000

In [5]:                                                                                         
Do you really want to exit ([y]/n)? y

stack39946052.py:20: TookTooLong: Terminating optimization: time limit reached
  TookTooLong)
....