RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1592325
Accepted
AnnaBazueva
AnnaBazueva
Asked:2024-08-30 11:25:39 +0000 UTC2024-08-30 11:25:39 +0000 UTC 2024-08-30 11:25:39 +0000 UTC

用于异常处理的动态代码生成(元编程)

  • 772

在选择这个问题的解决方案时,我想使用该模块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 全局错误保护也可以解决这个问题。

python
  • 1 1 个回答
  • 104 Views

1 个回答

  • Voted
  1. Best Answer
    AnnaBazueva
    2024-09-03T05:40:03Z2024-09-03T05:40:03Z

    我了解如何“从代码”pdb(.pdbrc 文件)执行命令,
    但这很难成为全局代码保护。

    我也发现了这个问题及其答案,
    如果有人设定了一个目标,甚至实现了这个目标,
    那么这将没有实际用途,
    因为总的来说,这些操纵的成本将非常高昂。


    不要仅仅因为你可以就这样做。

    • 0

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5