Python 隐藏回溯,除非设置了调试标志

Python 隐藏回溯,除非设置了调试标志,python,error-handling,user-experience,Python,Error Handling,User Experience,除非设置了详细或调试标志,否则python隐藏回溯错误的惯用方法是什么 示例代码: their_md5 = 'c38f03d2b7160f891fc36ec776ca4685' my_md5 = 'c64e53bbb108a1c65e31eb4d1bb8e3b7' if their_md5 != my_md5: raise ValueError('md5 sum does not match!') 现在已有输出,但仅在使用foo.py--debug调用时需要: Traceback (

除非设置了详细或调试标志,否则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!

下面是一个测试脚本:

短方法是使用
sys
模块并使用以下命令:

sys.tracebacklimit = 0
使用您的标志来确定行为

例如:

>>> import sys
>>> sys.tracebacklimit=0
>>> int('a')
ValueError: invalid literal for int() with base 10: 'a'
更好的方法是使用和:

编辑: 如果您仍然需要返回到原始挂钩的选项:

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\u hook
中不传递任何内容)。Python在定义时将默认参数绑定一次(常见的陷阱…),这使得它在被替换之前始终使用相同的原始处理程序。

我将恶毒地回答:

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))
不要隐藏回溯

回溯是向开发人员显示一个错误-未处理的异常。开发人员没有准备、没有注意到的东西。一句话——可憎

但你才是最聪明的。您可以看到,在某些情况下,md5总和不会太多,因此您应该结束您的程序。那么,让我们举个例子:

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)

     

当然,这些都是简化的示例…

谢谢!不过,我很难实现更好的方法。这对于用户友好的响应来说是完美的,但是我还不能详细地完成它<代码>打印回溯
仅显示对象名称,而
目录(回溯)
不显示我知道如何处理的任何内容。这就是我所拥有的:美丽的解决方案。您可以使用lambda:
sys.excepthook=lambda exctype,exc,traceback:print(“{}:{}”。format(exctype.\uuuu name\uuuuu,exc))
python3警报:上面带有
sys.tracebacklimit=0的示例不起作用。但是,定义的(且有洞察力的!)函数
exceptionHandler
工作正常,打印时通常会进行更改。您可以使用始终保持其原始定义的
sys.excepthook
,而不是依赖于在函数定义时未重新定义的
sys.\uu excepthook\uuu
,这确实应该是默认行为-添加一个回溯页面会让用户不太可能看到任何错误消息,因此这会适得其反,除非您是代码的实际开发人员。这会产生
TypeError:对于我来说,异常必须是旧式类或从BaseException派生的,而不是NoneType
(目前py v2.7.4)@matt:在哪一行?我没有2.7.4,所以我看不到错误。我的错误是,我在
调试:在
块之外提升
,除了…作为e:
块。现在在+1中工作,但我接受了Reut的答案,因为我不想在try中包装所有内容:…除了:
退出(-1)如果你在Spyder就不行。据我所知,加薪是唯一的出路。@Tunneller,Spyder到底是什么?你是说这个IDE()?嗯,我想说“是”,但Stackoverflow似乎想让我键入一个完整的句子?所以@ravenwing,“是”.所以…我会说这是python的答案,而不是IDE的特定答案。我很确定它没有使用自己的python实现。所以…更改您的IDE;p
if their_md5 != my_md5:
  sys.stderr.write('md5 sum does not match!')
  exit(-1)
 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)