首页 > 解决方案 > 我可以使用 IPython embed() 来更改函数的状态吗?

问题描述

是否可以在函数中嵌入 IPython 会话,以便对代码进行更改,就好像它在全局命名空间中一样?如果不是,为什么?还有其他选择吗?

从 IPython wiki 上关于从 Python 脚本内部嵌入 IPython 会话的条目:

需要注意的是,在嵌入式 IPython shell 中运行的代码不会改变代码和变量的状态,除非 shell 包含在全局命名空间中。

这种行为的一个小例子是从 IPython 会话中更改变量,该会话位于 Python REPL 中:

>>> from IPython import embed
>>> a = 12
>>> embed()

In [1]: a = 13

In [2]: exit()

>>> a
13

但是,当嵌入到函数中时:

>>> from IPython import embed
>>> def f():
...     x = 2
...     embed()
...     print(x)
... 
>>> f()

In [1]: x = 3

In [2]:                                                                  

2

虽然我不明白为什么必须这样(设计选择?技术问题?)我想在全局命名空间之外使用 IPython 更改我的代码,即一个函数,它应该是允许的行为,考虑到大多数结构良好的程序会尽可能少地留给全局命名空间(在我的情况下,我正在尝试更改我的main()功能)。

标签: pythonipython

解决方案


请不要这样做!这只是一个关于如何破解此设计功能的 PoC。

您可能不会找到不涉及类似问题的解决方案。但我将把它留在这里,这样你就可以看到潜在的解决方法有多难看。

from IPython import embed

def main():
  global g
  g = 40
  embed()
  print (g)

main()

现在在 IPython repl 中,我们执行以下操作:

Python 3.9.2 (default, Feb 27 2021, 00:33:24)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: g += 2

In [2]: globals().update(dict(g=g))

In [3]:

输出:

42

它不仅是 hacky,而且还涉及到全局命名空间,根据你的说法,这是不可取的。


推荐阅读