从更高级别引发异常,警告 [英] Raise an exception from a higher level, a la warnings

查看:56
本文介绍了从更高级别引发异常,警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在模块警告中 (https://docs.python.org/3.5/library/warnings.html) 有能力发出似乎来自堆栈中较早位置的警告:

In the module warnings (https://docs.python.org/3.5/library/warnings.html) there is the ability to raise a warning that appears to come from somewhere earlier in the stack:

warnings.warn('This is a test', stacklevel=2)

是否有引发错误的等价物?我知道我可以使用替代回溯引发错误,但我无法在模块中创建该回溯,因为它需要来自更早的时间.我想像这样:

Is there an equivalent for raising errors? I know I can raise an error with an alternative traceback, but I can't create that traceback within the module since it needs to come from earlier. I imagine something like:

tb = magic_create_traceback_right_here()
raise ValueError('This is a test').with_traceback(tb.tb_next)

原因是我正在开发一个具有函数 module.check_raise 的模块,我想引发一个错误,该错误似乎源自调用函数的位置.如果我在 module.check_raise 函数内引发错误,它似乎源自 module.check_raise 内,这是不希望的.

The reason is that I am developing a module that has a function module.check_raise that I want to raise an error that appears to originate from where the function is called. If I raise an error within the module.check_raise function, it appears to originate from within module.check_raise, which is undesired.

此外,我尝试了一些技巧,例如引发虚拟异常、捕获它并传递回溯,但不知何故 tb_next 变成了 None.我没有想法了.

Also, I've tried tricks like raising a dummy exception, catching it, and passing the traceback along, but somehow the tb_next becomes None. I'm out of ideas.

我想要这个最小示例(称为 tb2.py)的输出:

I would like the output of this minimal example (called tb2.py):

import check_raise

check_raise.raise_if_string_is_true('True')

仅此而已:

Traceback (most recent call last):
  File "tb2.py", line 10, in <module>
    check_raise.raise_if_string_is_true(string)
RuntimeError: An exception was raised.

推荐答案

我不敢相信我在发这个

这样做你违背了禅宗.

By doing this you are going against the zen.

特殊情况不足以打破规则.

Special cases aren't special enough to break the rules.

但如果你坚持,这里是你的魔法代码.

But if you insist here is your magical code.

import sys
import traceback

def raise_if_string_is_true(string):
    if string == 'true':
        #the frame that called this one
        f = sys._getframe().f_back
        #the most USELESS error message ever
        e = RuntimeError("An exception was raised.")

        #the first line of an error message
        print('Traceback (most recent call last):',file=sys.stderr)
        #the stack information, from f and above
        traceback.print_stack(f)
        #the last line of the error
        print(*traceback.format_exception_only(type(e),e),
              file=sys.stderr, sep="",end="")

        #exit the program
        #if something catches this you will cause so much confusion
        raise SystemExit(1)
        # SystemExit is the only exception that doesn't trigger an error message by default.

这是纯 python,不会干扰 sys.excepthook 并且即使在 try 块中它也不会被 except Exception: 捕获,尽管它被 捕获>除外:

This is pure python, does not interfere with sys.excepthook and even in a try block it is not caught with except Exception: although it is caught with except:

import check_raise

check_raise.raise_if_string_is_true("true")
print("this should never be printed")

会给你你想要的(非常缺乏信息和极度伪造的)回溯信息.

will give you the (horribly uninformative and extremely forged) traceback message you desire.

Tadhgs-MacBook-Pro:Documents Tadhg$ python3 test.py
Traceback (most recent call last):
  File "test.py", line 3, in <module>
    check_raise.raise_if_string_is_true("true")
RuntimeError: An exception was raised.
Tadhgs-MacBook-Pro:Documents Tadhg$

这篇关于从更高级别引发异常,警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆