我经常在其他Stack Overflow问题上看到关于如何不鼓励使用except: pass的评论。这为什么不好呢?有时我不在乎错误是什么,我只想继续写代码。

try:
    something
except:
    pass

为什么使用except: pass块不好?是什么让它变得糟糕?是我传递了一个错误还是我排除了任何错误?


当前回答

我正在构建一个将在数据中心运行的应用程序。它不应该生成任何错误或引发任何异常。我的数据中心有一个网络监控系统,其中包括一个SNMP trap接收器。

try:
    main()
except as e:
    log(str(e))
    send_snmp_trap(str(e))
    raise

但是这个加薪不会有任何效果因为它是和任何可能剩下的堆栈的底部。

顺便说一句,这不是万能的灵丹妙药。有一些例外情况是无法被发现的。SNMP不能保证传输。YMMV。

其他回答

except:pass构造本质上是在运行try:块中包含的代码时,使出现的任何和所有异常条件保持沉默。

这种糟糕的做法是因为它通常不是你真正想要的。更常见的情况是,出现一些特定的情况,你想要保持沉默,除了:pass是一个太生硬的工具。它将完成工作,但它也会掩盖其他错误条件,您可能没有预料到,但可能非常希望以其他方式处理。

What makes this particularly important in Python is that by the idioms of this language, exceptions are not necessarily errors. They're often used this way, of course, just as in most languages. But Python in particular has occasionally used them to implement an alternative exit path from some code tasks which isn't really part of the normal running case, but is still known to come up from time to time and may even be expected in most cases. SystemExit has already been mentioned as an old example, but the most common example nowadays may be StopIteration. Using exceptions this way caused a lot of controversy, especially when iterators and generators were first introduced to Python, but eventually the idea prevailed.

执行你的伪代码甚至不会给出任何错误:

try:
    something
except:
    pass

就好像它是一段完全有效的代码,而不是抛出NameError。我希望这不是你想要的。

>>> import this

The Zen of Python, by Tim Peters Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated. Flat is better than nested. Sparse is better than dense. Readability counts. Special cases aren't special enough to break the rules. Although practicality beats purity. Errors should never pass silently. Unless explicitly silenced. In the face of ambiguity, refuse the temptation to guess. There should be one-- and preferably only one --obvious way to do it. Although that way may not be obvious at first unless you're Dutch. Now is better than never. Although never is often better than right now. If the implementation is hard to explain, it's a bad idea. If the implementation is easy to explain, it may be a good idea. Namespaces are one honking great idea -- let's do more of those!

所以,这是我的观点。每当你发现一个错误,你应该做一些事情来处理它,即把它写在日志文件或其他东西。至少,它告诉您曾经有一个错误。

通常,您可以将任何错误/异常分为以下三类之一:

Fatal: Not your fault, you cannot prevent them, you cannot recover from them. You should certainly not ignore them and continue, and leave your program in an unknown state. Just let the error terminate your program, there is nothing you can do. Boneheaded: Your own fault, most likely due to an oversight, bug or programming error. You should fix the bug. Again, you should most certainly not ignore and continue. Exogenous: You can expect these errors in exceptional situations, such as file not found or connection terminated. You should explicitly handle these errors, and only these.

在除了:pass之外的所有情况下,pass只会让你的程序处于未知状态,在这种状态下它会造成更多的损害。

这里的主要问题是它忽略所有和任何错误:内存不足,CPU正在燃烧,用户想要停止,程序想要退出,Jabberwocky正在杀死用户。

这太过分了。在你的脑海中,你在想“我想忽略这个网络错误”。如果出现了意想不到的错误,那么您的代码将继续以完全不可预测的方式中断,没有人可以调试。

这就是为什么您应该限制自己只忽略一些错误,而让其余的错误过去。