在选择这个问题的解决方案时,我想使用该模块pdb
。
使用该模块,您可以通过
在控制台中输入适当的命令pdb
来更改变量并执行功能。
但我不明白如何以编程方式将命令发送到调试控制台。
使用 sys.stdout 进行拦截会导致与调试控制台发生冲突。(我尝试将拦截到的out添加到异步队列中并在另一个线程中处理它,但还没有成功。)pdb
现在我正在尝试通过上下文管理器。
这是代码:
import re
import sys
import pdb
import traceback
from contextlib import contextmanager
from rich import print, inspect
# Динамическое создание функций
def create_function(name):
def func(param):
print(f'{param}("{name}")')
return func
# Класс для перехвата вывода
class StreamInterceptor:
def __init__(self):
self.original_stdout = sys.stdout
def write(self, message):
# Перехватываем вывод и обрабатываем его
print(f"Перехваченный вывод: {message.strip()}")
def flush(self):
pass # Нужно для совместимости
def __enter__(self):
sys.stdout = self
return self
def __exit__(self, exc_type, exc_value, traceback):
sys.stdout = self.original_stdout
# Обработчик исключений
def my_except_hook(exctype, value, tb):
if exctype is not SystemExit:
tb_str = ''.join(traceback.format_exception(exctype, value, tb))
print(f"Обрабатываем исключение:\n{tb_str}")
# Извлечение имени функции из traceback
func_name = value.name
globals()[func_name] = create_function(func_name)
print(f'Создана функция: {func_name}')
inspect(globals()[func_name])
# Установка обработчика исключений
sys.excepthook = my_except_hook
# Используем контекстный менеджер для перехвата вывода
with StreamInterceptor():
# Устанавливаем точку останова перед вызовом функции
# pdb.set_trace()
Hello_world("print")
Hello_world("print")
It_is_not_print("print")
该函数my_except_hook
运行没有错误,该函数是动态创建的Hello_world
,并且该行显示在控制台中:print("Hello_world")
。
在上面的代码中,行:pdb.set_trace()
暂时被注释掉,但它的使用pdb
是必要的,因为即使处理的异常也会导致上下文管理器关闭。
查看输出:
Обрабатываем исключение:
Traceback (most recent call last):
File "c:\KWORK\not_print.py", line 73, in <module>
Hello_world("print")
^^^^^^^^^^^
NameError: name 'Hello_world' is not defined
Создана функция: Hello_world
╭─ <function create_function.<locals>.func at 0x00000162AFEC9120> ─╮
│ def create_function.<locals>.func(param): │
│ │
│ 38 attribute(s) not shown. Run inspect(inspect) for options. │
╰──────────────────────────────────────────────────────────────────╯
print("Hello_world")
代码需要继续执行,即lines: 72, 73, 74
必须实现,
这正是所需要的breakpoint()
。
互联网上有关主题的信息明显少于Django(例如)。
问题:
1. 如何使用该模块pdb
以编程方式输入命令,而不是(手动)进入控制台?
如何实现对所有代码的保护?
例如,在元编程时,您不必将每一行换行到try
-中,except
也不用将记录放入f.log
!?
PS 全局错误保护也可以解决这个问题。