如何嵌入ipython 0.12以便它继承调用者的命名空间?

时间:2012-03-26 12:56:23

标签: embed ipython

编辑我隔离了一个不起作用的真正的最小例子(它是更复杂代码的一部分);罪魁祸首毕竟是输入部分:

def foo():
    exec 'a=123' in globals()
    from IPython.frontend.terminal.embed import InteractiveShellEmbed
    ipshell=InteractiveShellEmbed()
    ipshell()

# without inputhook, 'a' is found just fine
import IPython.lib.inputhook
IPython.lib.inputhook.enable_gui(gui='qt4')

foo()

以0.12运行:

In [1]: a
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
/tmp/<ipython-input-1-60b725f10c9c> in <module>()
----> 1 a

NameError: name 'a' is not defined

会有什么方法?

1 个答案:

答案 0 :(得分:2)

问题是由于qt集成中的this callInteractiveShell.instance(),在初始化IPython之前调用时。如果在创建嵌入式shell之前调用此方法,则不会满足某些假设。修复是先创建嵌入式shell对象 ,然后就不会有任何问题。您只需调用InteractiveShellEmbed.instance()即可从代码中的任何其他位置检索相同的对象。

通过首先创建InteractiveShellEmbed实例 ,此版本应该可以正常工作:

from IPython.frontend.terminal.embed import InteractiveShellEmbed
# create ipshell *before* calling enable_gui
# it is important that you use instance(), instead of the class
# constructor, so that it creates the global InteractiveShell singleton
ipshell = InteractiveShellEmbed.instance()

import IPython.lib.inputhook
IPython.lib.inputhook.enable_gui(gui='tk')

def foo():
    # without inputhook, 'a' is found just fine
    exec 'a=123' in globals()
    # all calls to instance() will always return the same object
    ipshell = InteractiveShellEmbed.instance()
    ipshell()

foo()