通常,您应该“捕获”您预期会发生的异常(因为它们可能是由于用户错误或程序控制范围之外的其他环境问题引起的),尤其是在您知道代码可以对它们进行处理的情况下。仅在错误报告中提供更多详细信息是一个边际问题,尽管某些程序的规范可能需要这样做(例如,长时间运行的服务器,不应因此类问题而崩溃,而要记录许多状态信息,请提供用户进行简要说明,并继续为将来的查询工作)。
NameError,
TypeError,
KeyError,
ValueError,
SyntaxError,
AttributeError,等等,可以被认为是由于程序错误-
错误,不是程序员的控制范围之外的问题。如果您要发布一个库或框架,以致您的代码将被控件之外的其他代码调用,则此类错误很可能位于该其他代码中。您通常应该让异常传播,以帮助其他程序员调试自己的错误。如果要发布应用程序,则说明您拥有这些错误,并且必须选择可以帮助您找到它们的策略。
如果在最终用户运行程序时出现错误,则应记录很多状态信息,并向用户提供简要说明和歉意(如果无法发送请求,可能会请求向您发送日志信息)自动化-
或至少在将任何内容从用户计算机发送到您的计算机之前征得许可)。到目前为止,您也许可以保存一些用户的工作,但是经常(在已知为错误的程序中)可能仍然无法工作。
当然,大多数错误应在您自己的测试中显示。在这种情况下,传播异常非常有用,因为您可以将其连接到调试器并探查该错误的详细信息。
有时会出现诸如此类的异常,只是因为“请求宽容比许可容易”(EAFP),这是Python完全可接受的编程技术。在那种情况下,您当然应该立即处理它们。例如:
try: return mylist[theindex]except IndexError: return None
在这里,您可能会期望这
theindex通常是进入的有效索引
mylist,但有时会超出
mylists的范围-
而后一种情况(根据该代码段所属的假设应用的语义)不是错误,只是有点异常通过考虑将列表在概念上在两侧扩展为无限个
Nones来进行固定。仅尝试/例外要比正确检查索引的正负值容易(如果确实不常见,则越快越好)。
同样,由于dict的内置和方法(可让您提供默认值)等原因
KeyError,
AttributeError这种情况的发生和发生的频率也降低了;但是列表没有与之直接等效的列表,因此try
/ except在中更常见。
getattr``get``collections.defaultdict``IndexError
尝试捕获语法错误,类型错误,值错误,名称错误等的情况比较少见且更具争议性-
尽管如果在外部的“插件”,第三方代码中诊断出该错误,这肯定是合适的您的框架/应用程序试图动态加载和执行的控件(实际上是在提供库之类的情况下,需要与控件之外的代码和平共处,这可能很容易出错)。类型和值错误有时可能会在EAFP模式中发生-
例如,当您尝试重载函数以接受字符串或数字并且在每种情况下的行为略有不同时,捕获此类错误可能比尝试检查类型更好-但是,如此重载的功能的概念通常不是很可疑。
回到“用户和环境错误”,当用户给您输入内容时,用户不可避免地会犯错误,指出文件名实际上不存在(或您无权读取或写入,如果您要这样做的话)等等):当然应该捕获所有此类错误,并向用户清楚说明发生了什么问题,并为正确输入提供另一种机会。网络有时会出现故障,数据库或其他外部服务器可能无法按预期响应,依此类推-
有时值得发现此类问题并重试(也许稍等一会儿-可能向用户指示出了什么问题,例如可能是不小心拔掉了电缆,而您想给他们一个解决问题的机会,并告诉您何时重试),
因此,简而言之,对您的Q标题的答案是“取决于” ;-)。我希望我一直在列出它可能依赖的许多情况和方面,并推荐通常对此类问题最有用的态度。



