除非设置了详细或调试标志,否则隐藏回溯错误的惯用python方法是什么?
示例代码:
their_md5 = 'c38f03d2b7160f891fc36ec776ca4685'
my_md5 = 'c64e53bbb108a1c65e31eb4d1bb8e3b7'
if their_md5 != my_md5:
raise ValueError('md5 sum does not match!')
现在的输出,但仅在使用foo.py --debug
调用时才需要:
Traceback (most recent call last):
File "b:\code\apt\apt.py", line 1647, in <module>
__main__.__dict__[command] (packages)
File "b:\code\apt\apt.py", line 399, in md5
raise ValueError('md5 sum does not match!')
ValueError: md5 sum does not match!
所需的正常输出:
ValueError: md5 sum does not match!
这是一个测试脚本:https://gist.github.com/maphew/e3a75c147cca98019cd8
答案 0 :(得分:47)
简短的方法是使用sys
模块并使用此命令:
sys.tracebacklimit = 0
使用您的标志来确定行为。
示例:
>>> import sys
>>> sys.tracebacklimit=0
>>> int('a')
ValueError: invalid literal for int() with base 10: 'a'
更好的方法是使用和exception hook:
def exception_handler(exception_type, exception, traceback):
# All your trace are belong to us!
# your format
print "%s: %s" % (exception_type.__name__, exception)
sys.excepthook = exception_handler
如果你仍然需要选择回到原来的钩子:
def exception_handler(exception_type, exception, traceback, debug_hook=sys.excepthook):
if _your_debug_flag_here:
debug_hook(exception_type, exception, traceback)
else:
print "%s: %s" % (exception_type.__name__, exception)
现在您可以将调试挂钩传递给处理程序,但您很可能希望始终使用sys.excepthook
中的调用挂钩(因此debug_hook
中不传递任何内容)。 Python在定义时间(常见的陷阱...)中绑定默认参数一次,这使得它在替换之前始终使用相同的原始处理程序。
答案 1 :(得分:3)
try:
pass # Your code here
except Exception as e:
if debug:
raise # re-raise the exception
# traceback gets printed
else:
print("{}: {}".format(type(e).__name__, e))
答案 2 :(得分:0)
使用日志系统来处理错误输出。
我将使用请求连接错误作为示例用例,它生成 3 个异常的级联,每个异常都有很长的回溯。只有最终的错误消息才是真正重要的 - 被调用的服务正在拒绝,我不需要从我的客户端应用程序中知道 3 页的回溯!
# file: custom_exceptions.py
class Error(Exception):
"""This class should be used where traceback should not be logged"""
pass
try:
response = requests.get(url, auth=auth, headers=headers, timeout=TIMEOUT)
except requests.exceptions.ConnectionError as e:
raise custom_exceptions.Error(e)
except custom_exceptions.Error as e: # any custom error based on the custom Error class
if LOGLEVEL=logging.DEBUG:
logger.exception(e) # with traceback
else:
logger.error(e) # just the exception and message
exit()
except Exception as e:
logger.exception(e) # with traceback
exit()
由此产生的日志消息 - 此错误场景所需的所有详细信息:
2021-07-23 10:58:27,545 [ERROR] HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /next (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fc54f11f9d0>: Failed to establish a new connection: [Errno 111] Connection refused'))
答案 3 :(得分:-1)
我会邪恶地回答:
<块引用>不要隐藏回溯
Traceback 是向开发人员显示错误 - 未处理的异常。 delelopers 没有准备,没有注意到的东西。一个字——可憎。
但你是最聪明的人。您会看到有些情况下 md5 sum 不会太多,然后您将结束您的程序。所以也许让我们做精确的:
if their_md5 != my_md5:
sys.stderr.write('md5 sum does not match!')
exit(-1)
更重要的是 - 你的开发伙伴会很感激 - 他们仍然会有他们的回溯并且永远不会尝试处理这样的异常。 很快 - 如果您不想处理它,则没有理由引发异常。
但是……
如果你真的必须提出异常(所以也许会有一些可以接受的情况,你的开发伙伴想要处理它,例如使用 sha256,或者它只是巨大项目的一小部分),那么你可以这样做:
def do_sth_with_md5(their_md5, my_md5):
if their_md5 != my_md5:
raise ValueError('md5 sum does not match!')
actual_staff_to_do(their_md5, my_md5)
(...)
... somewhere else ...
try:
do_sth_with_md5(their, my)
except ValueError:
sys.stderr.write('md5 sum does not match!') #or sha256handling... whatever
exit(-1)
当然这些都是简化的例子...