如何更新ipdb中的嵌套函数?

时间:2019-01-11 20:52:45

标签: python ipython ipdb elpy

我正在用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中更新嵌套函数?

1 个答案:

答案 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