进行此类任意跳转的唯一方法是在CPython中,并且以的名称 实现详细信息
sys.settrace。
这是一个来自幽默的
goto愚人节模块的方法,它使我可以跳到(似乎)任意行:
import sysimport inspect_line_number = None_frame = Nonedef 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_numberdef _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 _tracedef install(): sys.settrace(_trace) frame = sys._getframe().f_back while frame: frame.f_trace = _trace frame = frame.f_back
如果我这样运行:
import tracehtraceh.install()import inspecttraceh.jump_to(10, inspect.currentframe())print(1)print(2)print(3)print(4)print(5)print(6)
我得到令人兴奋的输出:
Set jump to line 10 in tr.pyJumping to line 10 in tr.py456
现在,可以
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 tracehtraceh.install()raise NameErrorprint(5)print(6)
和输出…
Set jump to line 4 in tr.py
问题很明显:一旦调用sys.excepthook,外部作用域就消失了,因此绝对没有
_trace机会在原始文件中运行!
如果我们 假设 有解决方案,然后再使用
jump_to片刻,该怎么办?
import tracehtraceh.install()import inspecttry: 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.pyJumping to line 10 in tr.pycan't jump into the middle of a block
该死的
Richie Hindle将想法功劳归功于该
goto模块。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)