python - 我可以使用 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()
功能)。
解决方案
请不要这样做!这只是一个关于如何破解此设计功能的 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,而且还涉及到全局命名空间,根据你的说法,这是不可取的。
推荐阅读
- apache - 从 Apache Druid 删除列
- android - Android上通过BLE传输文件的问题
- python-3.x - Python 3 异常转换和重新引发
- laravel-5 - Laravel 迁移失败并出现 SQLSTATE[HY000]:一般错误:1215
- ios - 声明仅在文件范围错误时有效
- php - 如何调试冻结而不返回错误的脚本?(更新 SQL 表 - 大约 1.5 小时的过程)
- pyspark - 从嵌套的 json 文件中提取数据
- java - 每次在 Hibernate 中动态创建 EntityManager / 连接到自定义主机/数据库
- swift - 如何在swift 5中添加带有一个标签的表格视图页脚
- java - 创建 sql 查询时使用 java.text.MessageFormat.format() 是否安全?