我经常在其他Stack Overflow问题上看到关于如何不鼓励使用except: pass的评论。这为什么不好呢?有时我不在乎错误是什么,我只想继续写代码。
try:
something
except:
pass
为什么使用except: pass块不好?是什么让它变得糟糕?是我传递了一个错误还是我排除了任何错误?
我经常在其他Stack Overflow问题上看到关于如何不鼓励使用except: pass的评论。这为什么不好呢?有时我不在乎错误是什么,我只想继续写代码。
try:
something
except:
pass
为什么使用except: pass块不好?是什么让它变得糟糕?是我传递了一个错误还是我排除了任何错误?
当前回答
如果这是糟糕的做法,“通过”就不会是一个选项。 如果你有一个资产,从许多地方接收信息IE一个表单或userInput,它就会派上用场。
variable = False
try:
if request.form['variable'] == '1':
variable = True
except:
pass
其他回答
我个人更喜欢这个解决方案:
except ValueError as error:
print(error.args)
pass
错误。Args给了我一个简单的代码行,它不会太分散人的注意力,但确实有助于代码审查,特别是如果错误有不同的原因,比如
(ValueError('year 0 is out of range'),)
(ValueError('month must be in 1..12'),)
(ValueError('day is out of range for month'),)
当研究熊猫的时间周期时。
简单地说,如果抛出异常或错误,就说明出了问题。这可能不是什么非常错误的事情,但是仅仅为了使用goto语句而创建、抛出和捕获错误和异常并不是一个好主意,而且很少这样做。99%的情况下,都是某个地方出了问题。
问题需要处理。就像在生活中一样,在编程中,如果你把问题放在一边,试着忽略它们,很多时候它们不会自己消失;相反,它们变得越来越大,越来越多。为了防止一个问题在你身上滋生,并在将来再次出现,你要么1)消除它,然后清理混乱,要么2)控制它,然后清理混乱。
忽略异常和错误并让它们保持原样是体验内存泄漏、未完成的数据库连接、不必要的文件权限锁定等的好方法。
在极少数情况下,这个问题是如此微不足道,微不足道,而且——除了需要尝试……Catch block - self-contained,这样就真的没有什么乱七八糟的东西需要清理了。只有在这些情况下,这种最佳实践并不一定适用。根据我的经验,这通常意味着无论代码在做什么,基本上都是微不足道的,可以忽略的,而像重试尝试或特殊消息这样的事情既不值得复杂,也不值得暂停线程。
在我的公司,规则是几乎总是在catch块中做一些事情,如果你什么都不做,那么你必须总是放置一个注释,并给出一个很好的理由。当有事情要做的时候,你绝对不能错过或留下一个空的catch块。
首先,它违背了Python的两个禅宗原则:
显性比隐性好 错误绝不能悄无声息地过去
它的意思是,你故意让你的错误悄无声息地过去。此外,您不知道究竟发生了哪个错误,因为except: pass将捕获任何异常。
其次,如果我们试图从Python的禅意中抽象出来,而只是从理智的角度来说话,你应该知道,使用except:pass会让你在系统中失去知识和控制。经验法则是,如果发生错误,就引发异常,并采取适当的操作。如果你事先不知道这些操作应该是什么,至少在某个地方记录错误(最好重新引发异常):
try:
something
except:
logger.exception('Something happened')
但是,通常情况下,如果您试图捕获任何异常,那么您可能正在做错误的事情!
这里的主要问题是它忽略所有和任何错误:内存不足,CPU正在燃烧,用户想要停止,程序想要退出,Jabberwocky正在杀死用户。
这太过分了。在你的脑海中,你在想“我想忽略这个网络错误”。如果出现了意想不到的错误,那么您的代码将继续以完全不可预测的方式中断,没有人可以调试。
这就是为什么您应该限制自己只忽略一些错误,而让其余的错误过去。
因为它还没有被提及,所以使用contextlib.suppress是更好的风格:
with suppress(FileNotFoundError):
os.remove('somefile.tmp')
在本例中,somefile.tmp在执行此代码块后将不存在,而不会引发任何异常(除了FileNotFoundError,它被抑制)。