想象一下,我正在调试以下脚本:
import ipdb
def slow_function(something):
# I'm a very slow function
return something_else
def fast_function(something_else):
# There's a bug here
return final_output
something = 1
something_else = slow_function(something)
ipdb.set_trace()
final_output = fast_function(something_else)
ipdb.set_trace()
当满足ipdb.set_trace()
行时,会提示调试器shell,我现在可以执行final_output = fast_function(something_else)
语句来检查fast_function
是否按预期运行。我看到那里有一个bug,所以我进入源代码并修复它。现在我想看看修复是否正确,但我不想再次运行脚本(因为它很慢),也不想将something_else
保存在磁盘上(因为,也许,它非常大。)
有没有办法在调试器shell中更新fast_function()以便使用新的源代码?
答案 0 :(得分:4)
您可以在pdb中执行单行python语句,方法是在前面加上惊叹号。 pdb生成的help exec
输出如下:
(!) statement
Execute the (one-line) statement in the context of the current
stack frame. The exclamation point can be omitted unless the
first word of the statement resembles a debugger command. To
assign to a global variable you must always prefix the command
with a 'global' command, e.g.:
(Pdb) global list_options; list_options = ['-l']
(Pdb)
使用此工具,您可以将函数的源代码保存在文件中,并在pdb中更新该函数,如下所示:
!exec(open("fast_function.py", "r").read())
演示:
$ cat test.py
import pdb;
def foo():
print('Foo');
foo()
pdb.set_trace()
foo()
$ python3 test.py
Foo
> test.py(8)<module>()
-> foo()
(Pdb) cont
Foo
$ cat foo.py
def foo():
print('Modified Foo');
$ python3 test.py
Foo
> test.py(8)<module>()
-> foo()
(Pdb) !exec(open("foo.py", "r").read())
(Pdb) cont
Modified Foo
答案 1 :(得分:3)
如果它是一个短函数,你可以在一个pdb行中覆盖现有函数。请注意,惊叹号在那里是可选的。
(pdb)...
(pdb)!def fast_function(something_else): print("Hello world");return True
如果函数的代码长度稍大,那么您可以利用普通的交互式shell(see this)
(Pdb) !import code; code.interact(local=vars())
(InteractiveConsole)
In : def fast_function(something_else):
...: print 'hello in pdb'
...:
In : # use ctrl+d here to return to pdb shell...
(Pdb) !fast_function(arg)
hello in pdb
如果使用交互式shell无法轻松管理该函数的代码,Leons&#39;建议我会更好。
请记住,每个pdb行都可以像执行一行普通的python代码一样工作,你可以动态地完成任何事情!在这个意义上,pdb比其他一些图形调试工具更强大。
P.S。似乎PyCharm确实支持根据ADR评估表达特征
答案 2 :(得分:2)
编辑19/01/2018
您可以将结果写入内存中的文件。例如/ dev / shm是一个tmpfs分区。可以使用协议转储的keyargs优化大小。
# save result
with open('/dev/shm/data.pk', 'w' ) as data:
pickle.dump(something_else, data, protocole=3)
您可以使用pickle在第一次将结果存储到文件中并重新加载到调试第二个函数
import pickle
def slow_function(something):
# I'm a very slow function
return something + 42
def fast_function(something_else):
# There's a bug here
return something_else + 42
something = 1
something_else = slow_function(something)
# save result
with open('data.pk', 'w' ) as data:
pickle.dump(something_else, data)
第二次发布
import ipdb
# load result from disk
with open('data.pk', 'r' ) as data:
something_else = pickle.load(data)
ipdb.set_trace()
fast_function(something_else)