4m1*_*4j1 4 python api wrapper
我想使用raise而不在屏幕上打印回溯。我知道如何用那做try ..catch,但是没有找到一个办法raise。
下面是一个例子:
def my_function(self):
resp = self.resp
if resp.status_code == 404:
raise NoSuchElementError('GET'+self.url+'{}'.format(resp.status_code))
elif resp.status_code == 500:
raise ServerErrorError('GET'+self.url+'{}'.format(resp.status_code))
Run Code Online (Sandbox Code Playgroud)
执行此操作时,如果我有 404,则回溯将打印在屏幕上。
Traceback (most recent call last):
File "test.py", line 32, in <module>
print ins.my_function()
File "api.py", line 820, in my_function
raise NoSuchElementError('GET ' + self.url + ' {} '.format(resp.status_code))
Run Code Online (Sandbox Code Playgroud)
这是一个 API 包装器,我不希望用户看到回溯,而是希望看到 API 响应代码和错误消息。
有没有办法做到这一点?
问题不在于引发任何问题,而在于当程序因异常终止时(它只是打印堆栈跟踪)时 python 解释器所做的事情。如果你想避免它,你应该做的就是在你想要“隐藏”堆栈跟踪的所有内容周围放置 try except 块,例如:
def main():
try:
actual_code()
except Exception as e:
print(e)
Run Code Online (Sandbox Code Playgroud)
另一种方法是修改异常处理程序,sys.excepthook(type, value, traceback)以执行您自己的逻辑,例如
def my_exchandler(type, value, traceback):
print(value)
import sys
sys.excepthook = my_exchandler
Run Code Online (Sandbox Code Playgroud)
您甚至可以设置异常条件type并执行特定逻辑,当且仅当它是您的异常类型时,否则 - 退回到原始异常。
我遇到了一个类似的问题,其中父类使用异常值raise来传递消息,但我不想转储回溯。@lejlot 提供了一个很好的解决方案,sys.excepthook但我需要在更有限的范围内应用它。这是修改:
import sys
from contextlib import contextmanager
@contextmanager
def except_handler(exc_handler):
"Sets a custom exception handler for the scope of a 'with' block."
sys.excepthook = exc_handler
yield
sys.excepthook = sys.__excepthook__
Run Code Online (Sandbox Code Playgroud)
然后,使用它:
def my_exchandler(type, value, traceback):
print(': '.join([str(type.__name__), str(value)]))
with except_handler(my_exchandler):
raise Exception('Exceptional!')
# -> Exception: Exceptional!
Run Code Online (Sandbox Code Playgroud)
这样,如果块中未引发异常,则默认异常处理将针对任何后续异常恢复:
with except_handler(my_exchandler):
pass
raise Exception('Ordinary...')
# -> Traceback (most recent call last):
# -> File "raise_and_suppress_traceback.py", line 22, in <module>
# -> raise Exception('Ordinary...')
# -> Exception: Ordinary...
Run Code Online (Sandbox Code Playgroud)
小智 5
修改后的@Alec答案:
from contextlib import contextmanager
@contextmanager
def disable_exception_traceback():
"""
All traceback information is suppressed and only the exception type and value are printed
"""
default_value = getattr(sys, "tracebacklimit", 1000) # `1000` is a Python's default value
sys.tracebacklimit = 0
yield
sys.tracebacklimit = default_value # revert changes
Run Code Online (Sandbox Code Playgroud)
用法:
with disable_exception_traceback():
raise AnyYourCustomException()
Run Code Online (Sandbox Code Playgroud)
如果您只需要隐藏回溯而不修改异常消息,请使用此选项。在 Python 3.8 上测试
UPD:代码由 @DrJohnAStevenson 评论改进