我正在用Elpy在Emacs中运行IPython3,并尝试动态编辑嵌套函数。例如,我在一个框架中打开了附件,在另一框架中打开了IPython3。我使用C-c C-y b
将缓冲区发送到IPython,使用C-x o
切换到IPython框架。
import sys
def print_name():
print ("Alice")
def name ():
print_name()
def main(argv):
print ("In main.")
import ipdb; ipdb.set_trace()
name()
if __name__ == "__main__":
main(sys.argv[1:])
现在,我通过输入main(0)
来运行代码。
In [1]: main(0)
In main.
> /Users/ayank/Documents/programming/python/bar.py(12)main()
11 import ipdb; ipdb.set_trace()
---> 12 name()
13
我得到一个调试提示并执行:
ipdb> name()
Alice
现在,我返回print_name()
的代码窗口,将Alice
更改为Bob
,然后使用C-c C-y f
将函数重新发送到IPython3。我看到以下内容出现在IPython框架中:
ipdb> def print_name():
...: print ("Bob")
我回到IPython框架并输入:
ipdb> name()
Alice
ipdb> print_name()
Bob
那是不对的:两者都应打印Bob
。我可以使用C-c C-y b
将整个缓冲区重新发送到IPython,但是我得到的答案是:name()
总是输出Alice
。
这是怎么回事?调试时如何在IPython3中更新嵌套函数?
答案 0 :(得分:0)
问题在于,当执行达到断点时,在ipdb
提示符下键入的代码将在main
命名空间中执行。因此,新的print_name()
在main
命名空间中,而name()
继续在print_name()
命名空间中调用global
。
可以通过键入print_name()
将新的global
手动添加到globals()['print_name'] = print_name
命名空间中。
代码示例:
ayank@snorri$ ./foo.py
In main.
> /Users/ayank/Documents/programming/python/bar.py(13)main()
12 import ipdb; ipdb.set_trace()
---> 13 name()
14
ipdb> print_name()
Alice
ipdb> name()
Alice
ipdb> def print_name(): print ("Bob")
ipdb> print_name()
Bob
ipdb> name()
Alice
ipdb> globals()["print_name"] = print_name
ipdb> name()
Bob