gpt4 book ai didi

Python:使用自定义 sys.excepthook 在异常发生之前在上下文中的行号处恢复程序

转载 作者:太空宇宙 更新时间:2023-11-03 15:18:24 29 4
gpt4 key购买 nike

目标是在下面的代码中解析 os 依赖项并执行 ls 命令。

我想知道如何使用双星来完成我在下面的评论中提出的内容。

我已经知道我可以通过 traceback

获取行号

也就是说,我想知道是否有可能在给定上下文中的给定行号处恢复程序的执行。

import sys

def new_sys_excepthook(type, value, traceback):
if type == NameError:
pass
# Resolution of the exception finding the module dependency and doing the import
# ** Returning to the line that created the exception with the right
# ** context and continue the execution with the module
# ** dependency resolved
# call original excepthook if we can't solve the issue
sys.__excepthook__(type, value, traceback)

sys.excepthook = new_sys_excepthook

system("ls")

最佳答案

进行这种任意跳转的唯一方法是在 CPython 中,是一个实现细节,名称为 sys.settrace

这是一个取自幽默的 goto 愚人节模块的方法,它可以让我跳转到(看似)任意行:

import sys
import inspect

_line_number = None
_frame = None
def jump_to(line_number, frame):
global _line_number, _frame
print("Set jump to line", line_number, "in", inspect.getfile(frame))

_frame = frame
_line_number = line_number


def _trace(frame, event, arg):
global _line_number, _frame

try:
if _line_number is not None:
if inspect.getfile(_frame) == inspect.getfile(frame):
print("Jumping to line", _line_number, "in", inspect.getfile(frame))
frame.f_lineno = _line_number
_line_number = None

except ValueError as e:
print(e)

return _trace

def install():
sys.settrace(_trace)
frame = sys._getframe().f_back
while frame:
frame.f_trace = _trace
frame = frame.f_back

如果我这样运行它:

import traceh
traceh.install()

import inspect

traceh.jump_to(10, inspect.currentframe())
print(1)
print(2)
print(3)
print(4)
print(5)
print(6)

我得到了令人兴奋的输出:

Set jump to line 10 in tr.py
Jumping to line 10 in tr.py
4
5
6

现在我们可以将它嵌入 sys.excepthook 了吗?

...
def new_sys_excepthook(type, value, traceback):
if type == NameError:
jump_to(traceback.tb_lineno, traceback.tb_frame)
traceback.tb_frame
return

sys.__excepthook__(type, value, traceback)


def install():
sys.excepthook = new_sys_excepthook

sys.settrace(_trace)
...

并使用它:

import traceh
traceh.install()

raise NameError
print(5)
print(6)

输出...

Set jump to line 4 in tr.py

问题很明显:一旦调用 sys.excepthook,外部作用域就消失了,所以 _trace 根本没有机会在原始文件中运行!

如果我们假设有一个解决方案,然后回到使用 jump_to 一会儿会怎么样?

import traceh
traceh.install()

import inspect

try:
raise NameError
print(1)
print(2)
print(3)
print(4)
print(5)
print(6)

except:
traceh.jump_to(10, inspect.currentframe())

这不受我们上次看到的问题的影响,因为我们在文件中手动调用 jump_to。让我们看看:

Set jump to line 10 in tr.py
Jumping to line 10 in tr.py
can't jump into the middle of a block

该死的。

创意很大程度上归功于 goto module里奇·欣德尔 (Richie Hindle) 着。

关于Python:使用自定义 sys.excepthook 在异常发生之前在上下文中的行号处恢复程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18887163/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com