在使用python / ipython repl进行开发和调试时,我想在某个时候将函数中的所有局部变量转储到工作区,看看是怎么回事。假设我有一个功能
def func():
a = "blablabla"
b = 1234
c = some_calculation_of_a_and_b(a,b)
dump_to_workspace(a,b,c) # is this possible?, or even more preferable:
dump_all_local_variables_to_workspace() # is this possible?
我希望能在python / ipython中运行它:
>>> func()
>>> print a
"blablabla"
>>> print b
1234
>>> print c
some_calculated_value
我知道两种选择:(1)从函数中返回变量[不好因为我不想弄乱返回值],以及(2)将数据保存到磁盘上的文件中[不方便,因为它涉及可能有大量数据的磁盘I / O]。但是大多数时候这些并不方便。有没有办法直接实现倾销?
提前多多感谢!
答案 0 :(得分:1)
为了扩展我上面的评论,这里是pdb的快速介绍:
import pdb
def func():
a = "blablabla"
b = 1234
c = some_calculation_of_a_and_b(a,b)
pdb.set_trace()
运行:
python program.py
然后解释器将停在pdb.set_trace()行,允许您观察a
,b
和c
的值。
停止后,您可以通过键入以下内容来打印局部变量的值:
p a
p b
等。可以通过在pdb提示符下键入?
来获取pdb中的完整命令列表。 Here是图书馆文档的链接。
答案 1 :(得分:1)
要实现问题中直接要求的内容,该函数可以return locals()
,然后您可以在交互式环境中更新locals()
:
def func():
# define a,b,c
return locals() # or, more restrictively, return {'a':a, 'b':b, 'c':c}
>>> locals().update(func())
答案 2 :(得分:0)
你有一个功能:
print locals()
和globals()
表示全局变量
答案 3 :(得分:0)
你可以在ipython中使用whos
。
在python环境中vars()
。
答案 4 :(得分:0)
这是一个丑陋的hack,但是我经常在jupyter笔记本中使用它,以将某些局部状态转储到全局工作区中以进行进一步检查。只需将这两行添加到函数的末尾,然后您就可以直接从笔记本中访问所有局部变量:
import inspect
inspect.getmodule(next(frm[0] for frm in reversed(inspect.stack())
if frm[0].f_locals.get('__name__', None) == '__main__')).__dict__.update(locals())
它的作用是以相反的顺序遍历堆栈(使用inspect
模块)以找到名为'__main__'
的最顶部模块。那是代表笔记本的模块(即当前内核)。然后,它使用__dict__
和函数的本地变量(使用__locals__
)来更新模块的全局变量定义
这是笔记本中的演示: https://colab.research.google.com/drive/1lQgtmqigCUmzVhkX7H7azDWvT3CfxBtt
#%%
def some_calculation_of_a_and_b(a, b):
return 'some_calculated_value'
def func():
a = "blablabla"
b = 1234
c = some_calculation_of_a_and_b(a,b)
#dump_all_local_variables_to_workspace():
import inspect
inspect.getmodule(next(frm[0] for frm in reversed(inspect.stack())
if frm[0].f_locals.get('__name__', None) == '__main__')).__dict__.update(locals())
#%%
func()
print(a)
print(b)
print(c)
# this will print:
# blablabla
# 1234
# some_calculated_value
答案 5 :(得分:0)
我在 Jupyter 上下文中遇到了同样的问题。尤其是当您想使用 Jupyter 本身来帮助调试或绘制一些局部变量时,或者如果您想以交互方式编写旨在在深度嵌套函数中运行的代码,并且您想通过编写真实数据来构建它。>
Here's a github gist of a function to do this 大致基于上面 stav 的回答(笔记本的顶层与 ipython 不同)。 这是用 python 3.8 编写的,以防万一。
def copy_locals()
'''
copies all local variables from this context into the jupyter top level, eg, for easier
debugging of data and for prototyping new code that is eventually meant to run within this context.
'''
stack = inspect.stack()
caller = stack[1]
local_dict = {k:v for k,v in caller.frame.f_locals.items() if not k.startswith('_')}
notebook_caller = None
for st in stack:
if st.function == '<module>':
notebook_caller = st
break
if notebook_caller is None:
print('is this being called from within a jupyter notebook?')
return
print('copying variables to <module> globals...', list(local_dict.keys()))
notebook_caller.frame.f_globals.update(local_dict)
然后,如果您使用 breakpoint() 设置了断点,或者您已经崩溃并且您在 pdb 中,您可以在 pdb 中调用 copy_locals:
%debug
copy_locals()
并继续在笔记本上工作。