“我不知道这是不是出于无知,但我不喜欢这样
这是一种编程,因为它使用异常来执行流控制。”
在Python世界中,使用异常进行流控制是很常见和正常的。
即使是Python的核心开发人员也会使用异常来进行流控制,并且这种风格已经深深地嵌入到语言中(即迭代器协议使用StopIteration来发出循环终止的信号)。
此外,try-except-样式用于防止某些“三思而后行”构造中固有的竞争条件。例如,测试os.path.exists所得到的信息在您使用它时可能已经过时。同样地,队列。完整返回可能过期的信息。在这些情况下,try-except-else样式将生成更可靠的代码。
“根据我的理解,异常不是错误,它们应该只是
用于特殊情况"
在其他一些语言中,这一规则反映了他们的文化规范,就像他们的图书馆所反映的那样。该“规则”部分也是基于这些语言的性能考虑。
Python文化规范有些不同。在许多情况下,您必须为控制流使用异常。此外,在Python中使用异常不会像在一些编译语言中那样减慢周围的代码和调用代码(即CPython已经在每一步实现了异常检查的代码,不管你是否实际使用异常)。
换句话说,您理解的“异常适用于异常”的规则在其他一些语言中是有意义的,但对Python则不然。
然而,如果它包含在语言本身,就必须有一个
这是很好的理由,不是吗?”
除了有助于避免竞态条件,异常对于在外部循环中进行错误处理也非常有用。在解释性语言中,这是一个必要的优化,因为解释性语言往往没有自动循环不变的代码运动。
Also, exceptions can simplify code quite a bit in common situations where the ability to handle an issue is far removed from where the issue arose. For example, it is common to have top level user-interface code calling code for business logic which in turn calls low-level routines. Situations arising in the low-level routines (such as duplicate records for unique keys in database accesses) can only be handled in top-level code (such as asking the user for a new key that doesn't conflict with existing keys). The use of exceptions for this kind of control-flow allows the mid-level routines to completely ignore the issue and be nicely decoupled from that aspect of flow-control.
这里有一篇关于例外的必要性的不错的博客文章。
另外,请参阅Stack Overflow的回答:异常真的是针对异常错误的吗?
“除了别的尝试存在的原因是什么?”
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:
tests_run += 1
run_testcase(case)
except Exception:
tests_failed += 1
logging.exception('Failing test case: %r', case)
print('F', end='')
else:
logging.info('Successful test case: %r', case)
print('.', end='')
最后,在try-block中使用else子句最常见的用途是进行一些美化(将异常结果和非异常结果对齐在同一缩进级别)。这种用法总是可选的,并不是严格必要的。