在Python中使用try-except-else是个好习惯吗?

问题:

有时在Python中,我看到了块:

try:
   try_this(whatever)
except SomeException as exception:
   #Handle exception
else:
   return something

 除了否则存在的原因是什么?
我不喜欢这种编程,因为它使用异常来执行流控制。但是,如果它被包含在语言中,就必须有一个很好的理由,不是吗?
 我的理解是,异常并不是错误,并且它们应该仅用于异常条件(例如,我尝试将文件写入磁盘,没有更多空间,或者我没有权限),而不是用于流控制。
通常我处理例外:

something = some_default_value
try:
    something = try_this(whatever)
except SomeException as exception:
    #Handle exception
finally:
    return something

或者如果我真的不想返回任何东西,如果发生异常,那么:

try:
    something = try_this(whatever)
    return something
except SomeException as exception:
    #Handle exception

回答:

“我不知道这是不是无知,但我不喜欢这种编程,因为它使用异常来执行流控制。”

在Python世界中,使用异常来进行流量控制是常见且正常的。
即使Python核心开发人员使用流控制的异常,并且该风格被严重烧毁到语言中(即,迭代器协议使用StopIteration来信令循环终止)。
此外,try-except-style用于防止某些“look-before-you-leap”结构中固有的竞争条件。例如,测试os.path.exists会导致在您使用该信息时可能已过期的信息。同样,Queue.full返回可能会过时的信息。在这些情况下,try-except-else style将产生更可靠的代码。

“我的理解是,异常不是错误,它们只能用于特殊条件”

在其他一些语言中,这一规则反映了他们的图书馆所体现的他们的文化规范。 “规则”也部分地基于这些语言的性能考虑。
Python文化规范有些不同。在许多情况下,您must对控制流使用异常。另外,在Python中使用异常并不会像在一些编译语言中一样减慢周围的代码和调用代码(即,CPython已经在每一步都实现了用于异常检查的代码,而不管实际是否使用异常)。
换句话说,你的理解是“例外是特殊的”,这是一种在某些其他语言中是有意义的规则,但不适用于Python。

“但是,如果它包含在语言本身中,那就必须有很好的理由,不是吗?”

除了帮助避免竞争条件外,异常也是非常有用的拉出错误处理外部循环。这是解释型语言中必不可少的优化,这些语言不会有自动loop invariant code motion
此外,异常可以简化代码,在常见的情况下,处理问题的能力远远超出了问题出现的地步。例如,通常有业务逻辑的顶级用户界面代码调用代码,这又调用低级例程。在低级例程中出现的情况(例如数据库访问中唯一键的重复记录)只能在顶级代码中处理(例如向用户询问与现有键不冲突的新密钥)。对这种控制流的使用异常允许中级例程完全忽略该问题,并从流控制的方面很好地解耦。
有一个nice blog post on the indispensibility of exceptions here
另请参阅StackOverFlow答案:Are exceptions really for exceptional errors?

“除了否则存在的原因是什么?”

else子句本身很有趣。当没有例外但在finally子句之前运行它。这是它的主要目的。
没有else子句,在完成之前运行附加代码的唯一选择是将代码添加到try子句中的笨拙习惯。这是笨拙的,因为它有风险
在不受try块保护的代码中引发异常。
在最终确定之前运行附加的未受保护的代码的用例并不常出现。所以,不要指望在发布的代码中看到很多例子。有点罕见。
else子句的另一个用例是执行不发生异常时必须发生的操作,并且在处理异常时不发生。例如:

   recip = float('Inf')
   try:
       recip = 1 / f(x)
   except ZeroDivisionError:
       logging.info('Infinite result')
   else:
       logging.info('Finite result')

最后,try-block中else子句的最常用的方法是进行一些美化(将异常结果与非特殊结果对齐在同一级别的缩进)。这种使用始终是可选的,并不是绝对必要的。

 
 Code问答: codewenda.com
Stackoverflow:Is it a good practice to use try-except-else in Python?

发表评论

电子邮件地址不会被公开。 必填项已用*标注

14 − 8 =