当我在 IDE(例如 PyCharm)中单步执行代码时,我想转储函数的参数(以供以后使用,例如复制它)。 计划的场景是在某处设置断点,然后引发异常(这不在我运行的代码中,这就是重点),并捕获它。
代码应该如下所示:
def exception_cathcher_decorator(func):
try:
return func(*f_args, **f_kwargs)
except Exception:
print("Here comes the dumping code.")
@exception_cathcher_decorator
def some_dummy_function(some_args):
...
print("The breakpoint is in this line")
...
什么是重要的是,在 some_dummy_function 中不会引发任何异常,这应该来自任何地方(可能评估 IDE 中的某些代码等) exception_cathcher_decorator 应该来自我的开发作为导入,但现在它并不重要。装饰器是可以在审查函数时添加的(并且可以稍后删除),这就是使用装饰器的原因。
理论上可能吗?有什么想法可以达到这个目的吗?
(仅供参考,如果我们想要重新创建函数的运行上下文,那么此功能将很有帮助,这在开发时是理想的选择。某些函数状态的重新创建非常耗时,甚至达到它们也很复杂.)
在 Python 中,虽然不能直接从 IDE 的调试步骤中“抛出”异常,但你可以模拟类似的行为来达到你的目的。
以下是几种方法:
方法一:使用
sys.settrace
和条件断点
-
设置跟踪函数:
使用
sys.settrace
可以设置一个回调函数,它会在解释器执行每条语句时被调用。 - 条件断点: 在你的跟踪函数中,检查当前执行的行号是否是你想要触发“异常”的地方。
- 抛出异常: 如果满足条件,则抛出一个自定义异常。
import sys
import traceback
def debug_hook(frame, event, arg):
if event == 'line' and frame.f_lineno == 7: # 检查是否为目标行号
raise DumpArgsException()
return debug_hook
sys.settrace(debug_hook)
def exception_catcher_decorator(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except DumpArgsException:
print("Here comes the dumping code.")
traceback.print_stack(frame) # 打印调用堆栈
# 在这里你可以访问 args 和 kwargs 进行转储
return wrapper
class DumpArgsException(Exception):
pass
@exception_catcher_decorator
def some_dummy_function(some_arg1, some_arg2):
print("Before the breakpoint") # 行号 6
print("The breakpoint is in this line") # 行号 7
print("After the breakpoint")
some_dummy_function("arg1", "arg2")
sys.settrace(None) # 关闭跟踪
方法二:使用调试器的条件断点功能
大多数 IDE 的调试器都支持条件断点。你可以在断点处设置条件,当条件满足时,断点才会被触发。
- 在目标行设置断点。
- 右键单击断点,选择“Edit Breakpoint” 或类似选项。
-
在“Condition” 字段中输入
True
以外的任何表达式,例如1 == 2
。 - 当程序运行到该断点时,条件不满足,因此不会停止。但是,你可以利用这个机会在调试器的控制台中手动抛出你的异常。
一些额外的建议:
-
为了更方便地转储参数,可以考虑使用
pprint
模块来格式化输出。 - 你也可以将转储的函数参数保存到文件中,方便后续分析。
需要注意的是,这两种方法都依赖于在代码中添加一些额外的逻辑。如果你的目标是在不修改代码的情况下实现这个功能,那么可能需要寻找其他方法,例如使用更高级的调试工具或字节码注入技术。
标签:python,exception,ide From: 78815436