Python使用异常进行控制流被认为是不好的吗? [英] Python using exceptions for control flow considered bad?

查看:51
本文介绍了Python使用异常进行控制流被认为是不好的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好的,

我过去曾多次见过这种情况,但最近一次是

I've seen this multiple times in the past, but most recently with my question here. So, I'm curious why this is the case, in python because generators use exceptions to indicate the end of the data.

如果这对于使用python的每个人来说都很糟糕,为什么该语言将其包含在被认为是基本控制结构的内容中?对于那些想阅读相关PEP的人,请转到此处.

If this is so bad for everyone using python, why does the language include it in what are considered fundamental control structures? For those who want to read the relevant PEP go here.

推荐答案

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

Because ending the generator is not a common event (I know it will always happen, but it only happens once). Throwing the exception is considered expensive. If an event is going to succeed 99% of the time and fail 1%, using try/except can be much faster than checking if it's okay to access that data (it's easier to ask forgiveness than permission).

还有一个偏见,因为这样的try/except块可能很难理解.流量控制可能很难遵循,而if/else更简单. try/except意味着您必须在其调用的函数内的try 内部跟踪语句的流控制(因为它们可能引发异常,并且可能向上传播.if/else可以仅在评估语句时分支.

There's also a bias against it since try/except blocks used like that can be very difficult to understand. The flow control can be difficult to follow, while an if/else are more straightforward. The try/except means you have to track the flow control of the statements inside the try and inside of the functions it calls (as they may throw the exception and it may propagate upwards. An if/else can only branch at the point when the statement is evaluated.

有时候使用try/except是正确的,而使用if/else更有意义.它们每个都有相关的性能成本.考虑:

There are times when using try/except is correct and times when if/else make more sense. There are also performance costs associated with each of them. Consider:

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

vs.

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

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

The first will be faster if key does not exist inside of a and will only be slightly (almost unnoticeable) slower if it does exist. The second will be faster if the key does exist, but will be much slower if it doesn't exist. If key almost always exists, you go with the second. Otherwise, the first works better.

仅需添加一点关于Python try/的信息,否则将大大有助于解决其中之一的可读性问题.

Just a little thing to add about Python try/except that helps greatly with one of the readability problems.

考虑从文件中读取.

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中的任何内容都可以引发异常,我们将捕获该异常.通常,由于这个原因,您尝试在尝试中保留尽可能少的代码. Python为try提供了一个可选的else子句,该子句只有在try运行完成而没有遇到异常的情况下才会运行.

Now anything in the do stuff to the file can throw an exception and we'll catch it. Commonly, you try to keep as little code as possible in the try for this reason. Python has an optional else clause for the try that will only be run if the try ran to completion without hitting an exception.

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

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

In this case, you would not have any of the readability problems since only one statement is in the try; it is a python standard library function call and you're catching only specific exceptions.

这篇关于Python使用异常进行控制流被认为是不好的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆