2

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 标记了这个问题。

4

2 回答 2

8

这被称为EAFP比许可更容易请求宽恕。来自Python 词汇表

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

LBYL 的意思是在你跳跃之前先看。再次来自Python 词汇表

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

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

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

在使用 Python(或任何语言)编写时,遵循该语言的习惯用法会有所帮助,这使您的代码更容易被阅读它的其他人理解。

于 2013-05-08T22:28:10.297 回答
0

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

于 2013-05-08T22:42:31.227 回答