使用异常来控制代码流

时间:2013-05-08 22:25:22

标签: python exception

afaik使用异常处理代码流是错误的。我正在使用一个名为getEntity(id)的方法的代码,并且当找不到实体时,getEntity会抛出一个DoesNotExist异常。没有entityExists(id)方法。要检查实体是否存在,代码通常会执行:

try: 
   getEntity(id)
catch DoesNotExist as e:
   # entity does not exist

在我看来,这会更好:

if not entityExists(id):
   # entity does not exist

这是常识吗?我认为代码是这样的,因为它使用Django并且它正在复制Django异常名称(DoesNotExist)以及它处理实体不存在的常用方法。

这个问题并不是特定于Python,但我使用的代码是Python中的代码,因此我用Python标记了这个问题。

2 个答案:

答案 0 :(得分:8)

这被称为EAFP更容易要求宽恕而不是许可。来自The Python Glossary

  

这种常见的Python编码风格假设存在有效的键或属性,并且如果假设被证明是错误则捕获异常。这种干净快速的风格的特点是存在许多tryexcept语句。该技术与LBYL等许多其他语言共有的风格形成对比。

LBYL表示在你跳跃之前先看看。再次来自The Python Glossary

  

此编码样式在进行调用或查找之前显式测试前置条件。这种风格与EAFP方法形成对比,其特点是存在许多if语句。

然后继续为你的if not entityExists(id):建议提供一个很好的反例:

  

在多线程环境中,LBYL方法可能会冒险在“外观”和“跳跃”之间引入竞争条件。例如,如果另一个线程在测试之后但在查找之前从映射中删除了键,则代码if key in mapping: return mapping[key]可能会失败。这个问题可以通过锁定或使用EAFP方法来解决。

使用Python(或任何语言)编写时,有助于遵循该语言的习语,这使得您的代码更易于被其他人阅读。

答案 1 :(得分:0)

在我看来,这取决于具体情况。如果您确定确定所有可能的结果,请继续执行您的if / elses(LBYL)。如果您不确定可能的结果(例如在处理未知类型的变量时),请尝试/ catch(EAFP)是一种更安全的方法。