繁体   English   中英

Python 使用异常进行控制流被认为不好?

[英]Python using exceptions for control flow considered bad?

好的,

过去我已经多次看到这种情况,但最近我的问题在这里 所以,我很好奇为什么会这样,在 python 中,因为生成器使用异常来指示数据的结尾。

如果这对使用 python 的每个人来说都如此糟糕,为什么该语言将它包含在被认为是基本控制结构中? 对于那些想要阅读相关 PEP 的人,请访问这里

因为结束生成器不是一个常见的事件(我知道它总是会发生,但它只会发生一次)。 抛出异常被认为是昂贵的。 如果一个事件有 99% 的成功率和 1% 的失败率,那么使用 try/except 比检查是否可以访问该数据要快得多(请求宽恕比请求许可更容易)。

也有对它的偏见,因为像这样使用的 try/except 块可能很难理解。 流控制可能难以遵循,而 if/else 则更直接。 在try /只是意味着你要跟踪它调用的函数的尝试内内的语句的流控制(因为它们可能会抛出异常,它可以向上传播。if / else语句可以在唯一分支机构在点时语句被评估。

有时使用 try/except 是正确的,有时使用 if/else 更有意义。 还有与它们中的每一个相关的性能成本。 考虑:

a = <some dictionary>
if key in a:
    print a[key]

对比

a = <some dictionary>
try:
    print a[key]
except KeyError:
    pass

如果 key 不存在于 a 中,第一个会更快,如果它确实存在,则只会稍微(几乎不明显)更慢。 如果键确实存在,第二个会更快,但如果它不存在,则会慢得多。 如果 key 几乎总是存在,则选择第二个。 否则,第一个效果更好。

编辑:只需添加关于 Python try/except 的一点东西,这对解决可读性问题之一有很大帮助。

考虑从文件中读取。

f = None
try:
    f = open(filename, 'r')
    ... do stuff to the file ...
except (IOError, OSError):
    # I can never remember which one of these Python throws...
    ... handle exception ...
finally:
    if f:
        f.close()

现在do stuff to the file任何do stuff to the file都可能引发异常,我们将捕获它。 通常,出于这个原因,您会尝试在 try 中保留尽可能少的代码。 Python 有一个可选的else子句用于 try ,只有当 try 运行完成而没有遇到异常时才会运行。

f = None
try:
    f = open(filename, 'r')
except (IOError, OSError):
    pass
else:
    ... do stuff to the file ...
finally:
    if f:
        f.close()

在这种情况下,您不会遇到任何可读性问题,因为 try 中只有一个语句; 它是一个 python 标准库函数调用,您只捕获特定的异常。

因为异常是在堆栈上引发的,所以它们适用于某些情况,即您希望使用其他代码的代码能够捕获异常。 例如,考虑到您想要创建一个迭代器的情况,该迭代器更“手动”地使用另一个迭代器的一部分,拥有一个可以从堆栈的更高层捕获并插入您自己的逻辑的异常是很有价值的。

一直使用try块进行流量控制可能会产生如下代码:

try:
  # stuff
  try:
    if userCondition:
      throw NeedToDoSomethingElseException
    try:
      # stuff
    except NeedToDoSomethingElseException:
      # other stuff
  except NeedToDoSomethingElseException:
    # other stuff
except NeedToDoSomethingElseException:
  # other stuff

撇开性能问题不谈,这不是很优雅。 因此,有时使用try非常合适,但并非适用于所有情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM