本文翻译自:Is it a good practice to use try-except-else in Python?

From time to time in Python, I see the block: 在Python中,我不时看到该块:

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

What is the reason for the try-except-else to exist? try-except-else存在的原因是什么?

I do not like that kind of programming, as it is using exceptions to perform flow control. 我不喜欢这种编程,因为它使用异常来执行流控制。 However, if it is included in the language, there must be a good reason for it, isn't it? 但是,如果它包含在语言中,则一定有充分的理由,不是吗?

It is my understanding that exceptions are not errors , and that they should only be used for exceptional conditions (eg I try to write a file into disk and there is no more space, or maybe I do not have permission), and not for flow control. 据我了解,异常不是错误 ,并且仅应将其用于特殊情况(例如,我尝试将文件写入磁盘,并且没有更多空间,或者我没有权限),而不是流控制。

Normally I handle exceptions as: 通常,我将异常处理为:

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

Or if I really do not want to return anything if an exception happens, then: 或者,如果发生异常,我真的不想返回任何东西,那么:

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

#1楼

参考:https://stackoom.com/question/15iI4/在Python中使用try-except-else是否是一种好习惯


#2楼

Python doesn't subscribe to the idea that exceptions should only be used for exceptional cases, in fact the idiom is 'ask for forgiveness, not permission' . Python不赞成将异常仅用于特殊情况的想法,实际上,习惯用法是“要求宽恕,而不是允许” 。 This means that using exceptions as a routine part of your flow control is perfectly acceptable, and in fact, encouraged. 这意味着使用异常作为流程控制的常规部分是完全可以接受的,并且实际上是受鼓励的。

This is generally a good thing, as working this way helps avoid some issues (as an obvious example, race conditions are often avoided), and it tends to make code a little more readable. 这通常是一件好事,因为以这种方式工作有助于避免某些问题(显而易见的示例是,通常避免出现竞争条件),并且往往会使代码更具可读性。

Imagine you have a situation where you take some user input which needs to be processed, but have a default which is already processed. 假设您遇到这样一种情况,您需要处理一些用户输入,但是已经处理了默认输入。 The try: ... except: ... else: ... structure makes for very readable code: try: ... except: ... else: ...结构使得代码易于阅读:

try:raw_value = int(input())
except ValueError:value = some_processed_value
else: # no error occuredvalue = process_value(raw_value)

Compare to how it might work in other languages: 与其他语言可能的工作方式进行比较:

raw_value = input()
if valid_number(raw_value):value = process_value(int(raw_value))
else:value = some_processed_value

Note the advantages. 注意优点。 There is no need to check the value is valid and parse it separately, they are done once. 无需检查该值是否有效并单独对其进行分析,只需完成一次即可。 The code also follows a more logical progression, the main code path is first, followed by 'if it doesn't work, do this'. 代码也遵循更合理的顺序,首先是主要代码路径,然后是“如果不起作用,请执行此操作”。

The example is naturally a little contrived, but it shows there are cases for this structure. 该示例自然有点虚构,但它显示了这种结构的情况。


#3楼

You should be careful about using the finally block, as it is not the same thing as using an else block in the try, except. 您应该谨慎使用finally块,因为它与try中使用else块的功能不同,除了。 The finally block will be run regardless of the outcome of the try except. 无论try的结果如何,都将运行finally块。

In [10]: dict_ = {"a": 1}In [11]: try:....:     dict_["b"]....: except KeyError:....:     pass....: finally:....:     print "something"....:
something

As everyone has noted using the else block causes your code to be more readable, and only runs when an exception is not thrown 正如每个人都指出的那样,使用else块会使您的代码更具可读性,并且仅在未引发异常时运行

In [14]: try:dict_["b"]except KeyError:passelse:print "something"....:

#4楼

"I do not know if it is out of ignorance, but I do not like that kind of programming, as it is using exceptions to perform flow control." “我不知道它是否出于无知,但我不喜欢这种编程,因为它使用异常来执行流控制。”

In the Python world, using exceptions for flow control is common and normal. 在Python世界中,使用异常进行流控制是常见且正常的。

Even the Python core developers use exceptions for flow-control and that style is heavily baked into the language (ie the iterator protocol uses StopIteration to signal loop termination). 甚至Python核心开发人员也将异常用于流控制,并且该样式已在语言中大量使用(即,迭代器协议使用StopIteration来指示循环终止)。

In addition, the try-except-style is used to prevent the race-conditions inherent in some of the "look-before-you-leap" constructs. 此外,try-except样式用于防止某些“跨越式”构造固有的竞争条件。 For example, testing os.path.exists results in information that may be out-of-date by the time you use it. 例如,测试os.path.exists会导致信息在您使用时已过时。 Likewise, Queue.full returns information that may be stale. 同样, Queue.full返回的信息可能已过时。 The try-except-else style will produce more reliable code in these cases. 在这种情况下, try-except-else样式将产生更可靠的代码。

"It my understanding that exceptions are not errors, they should only be used for exceptional conditions" “据我了解,异常不是错误,它们仅应用于特殊情况”

In some other languages, that rule reflects their cultural norms as reflected in their libraries. 在其他一些语言中,该规则反映了图书馆所反映的文化规范。 The "rule" is also based in-part on performance considerations for those languages. 该“规则”还部分基于这些语言的性能考虑。

The Python cultural norm is somewhat different. Python的文化规范有些不同。 In many cases, you must use exceptions for control-flow. 在许多情况下, 必须对控制流使用例外。 Also, the use of exceptions in Python does not slow the surrounding code and calling code as it does in some compiled languages (ie CPython already implements code for exception checking at every step, regardless of whether you actually use exceptions or not). 另外,在Python中使用异常不会像在某些编译语言中那样降低周围的代码和调用代码的速度(即CPython已经在每一步实现了用于异常检查的代码,无论您是否实际使用异常)。

In other words, your understanding that "exceptions are for the exceptional" is a rule that makes sense in some other languages, but not for Python. 换句话说,您理解“例外是为了例外”是一条在其他语言中有意义的规则,但不适用于Python。

"However, if it is included in the language itself, there must be a good reason for it, isn't it?" “但是,如果它本身包含在语言中,那一定有充分的理由,不是吗?”

Besides helping to avoid race-conditions, exceptions are also very useful for pulling error-handling outside loops. 除了帮助避免竞争条件外,异常对于在循环外拉出错误处理也非常有用。 This is a necessary optimization in interpreted languages which do not tend to have automatic loop invariant code motion . 这是解释语言中的必要优化,这些语言通常不会具有自动循环不变的代码运动 。

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. 对此类控制流使用异常可以使中级例程完全忽略该问题,并将其与流控制的这一方面很好地分离。

There is a nice blog post on the indispensibility of exceptions here . 这里有一篇关于异常不可或缺的不错的博客文章 。

Also, see this Stack Overflow answer: Are exceptions really for exceptional errors? 另外,请参见此堆栈溢出答案: 异常确实是异常错误的吗?

"What is the reason for the try-except-else to exist?" “ try-except-else存在的原因是什么?”

The else-clause itself is interesting. 其他条款本身很有趣。 It runs when there is no exception but before the finally-clause. 它在没有例外的情况下运行,但是在最终条款之前。 That is its primary purpose. 这是其主要目的。

Without the else-clause, the only option to run additional code before finalization would be the clumsy practice of adding the code to the try-clause. 如果没有else子句,那么在最终确定之前运行其他代码的唯一选择就是将代码添加到try子句的笨拙做法。 That is clumsy because it risks raising exceptions in code that wasn't intended to be protected by the try-block. 这很笨拙,因为它冒着在代码中引发异常的危险,而这些异常本来不会受到try块的保护。

The use-case of running additional unprotected code prior to finalization doesn't arise very often. 在完成之前运行其他不受保护的代码的用例很少出现。 So, don't expect to see many examples in published code. 因此,不要期望在已发布的代码中看到很多示例。 It is somewhat rare. 这有点罕见。

Another use-case for the else-clause is to perform actions that must occur when no exception occurs and that do not occur when exceptions are handled. else子句的另一个用例是执行在没有异常发生时必须发生的动作以及在处理异常时不发生的动作。 For example: 例如:

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

Another example occurs in unittest runners: 另一个示例发生在单元测试赛跑者中:

try:tests_run += 1run_testcase(case)
except Exception:tests_failed += 1logging.exception('Failing test case: %r', case)print('F', end='')
else:logging.info('Successful test case: %r', case)print('.', end='')

Lastly, the most common use of an else-clause in a try-block is for a bit of beautification (aligning the exceptional outcomes and non-exceptional outcomes at the same level of indentation). 最后,在try-block中,else-clause的最常见用法是用于一些美化(在相同的缩进级别上对齐例外结果和非例外结果)。 This use is always optional and isn't strictly necessary. 此用法始终是可选的,并非严格必要。


#5楼

Is it a good practice to use try-except-else in python? 在python中使用try-except-else是否是一种好习惯?

The answer to this is that it is context dependent. 答案是它取决于上下文。 If you do this: 如果您这样做:

d = dict()
try:item = d['item']
except KeyError:item = 'default'

It demonstrates that you don't know Python very well. 它表明您不太了解Python。 This functionality is encapsulated in the dict.get method: 此功能封装在dict.get方法中:

item = d.get('item', 'default')

The try / except block is a much more visually cluttered and verbose way of writing what can be efficiently executing in a single line with an atomic method. try / except块是一种在视觉上更加混乱和冗长的方式,可以用原子方法在一行中有效执行代码。 There are other cases where this is true. 在其他情况下,这是正确的。

However, that does not mean that we should avoid all exception handling. 但是,这并不意味着我们应该避免所有异常处理。 In some cases it is preferred to avoid race conditions. 在某些情况下,最好避免比赛条件。 Don't check if a file exists, just attempt to open it, and catch the appropriate IOError. 不要检查文件是否存在,只需尝试将其打开并捕获相应的IOError。 For the sake of simplicity and readability, try to encapsulate this or factor it out as apropos. 为了简单起见,请尝试将其封装或分解为适当的名称。

Read the Zen of Python , understanding that there are principles that are in tension, and be wary of dogma that relies too heavily on any one of the statements in it. 阅读Python的Zen ,了解其中存在一些紧绷的原则,并且要警惕过于依赖其中任何一种陈述的教条。


#6楼

OP, YOU ARE CORRECT. OP,您是正确的。 The else after try/except in Python is ugly . 在Python中try / except之后的else很难看 it leads to another flow-control object where none is needed: 它导致另一个不需要的流控制对象:

try:x = blah()
except:print "failed at blah()"
else:print "just succeeded with blah"

A totally clear equivalent is: 完全清楚的等效项是:

try:x = blah()print "just succeeded with blah"
except:print "failed at blah()"

This is far clearer than an else clause. 这比else子句清楚得多。 The else after try/except is not frequently written, so it takes a moment to figure what the implications are. try / except之后的else不经常编写,因此花一点时间弄清楚其含义是什么。

Just because you CAN do a thing, doesn't mean you SHOULD do a thing. 仅仅因为您可以做某事,并不意味着您应该做某事。

Lots of features have been added to languages because someone thought it might come in handy. 许多功能已添加到语言中,因为有人认为它可能派上用场。 Trouble is, the more features, the less clear and obvious things are because people don't usually use those bells and whistles. 麻烦的是,功能越多,事物的清晰度和显而易见性就越差,这是因为人们通常不使用这些铃声。

Just my 5 cents here. 这里只有我的5美分。 I have to come along behind and clean up a lot of code written by 1st-year out of college developers who think they're smart and want to write code in some uber-tight, uber-efficient way when that just makes it a mess to try and read / modify later. 我必须走到后面,清理掉大学一年级学生编写的许多代码,这些开发人员认为他们很聪明,并希望以超级严格,超级高效的方式编写代码,这只会使事情变得一团糟以尝试稍后阅读/修改。 I vote for readability every day and twice on Sundays. 我每天对可读性进行投票,而星期日则两次。

在Python中使用try-except-else是否是一种好习惯?相关推荐

  1. Python中斐波那契数列的四种写法

    在这些时候,我可以附和着笑,项目经理是决不责备的.而且项目经理见了孔乙己,也每每这样问他,引人发笑.孔乙己自己知道不能和他们谈天,便只好向新人说话.有一回对我说道,"你学过数据结构吗?&qu ...

  2. python中交换两个变量值的几种方式?

    python中交换两个变量值的几种方式 1.python中独有的,也是最简单的方式: a,b=b,a 2.引入第三个变量,可以看作两个装满牛奶的瓶子a和瓶子b,如果我想交换这两个瓶子中的牛奶,就需要一 ...

  3. python中保留小数_python保留小数位的三种实现方法

    前言 保留小数位是我们经常会碰到的问题,尤其是刷题过程中.那么在python中保留小数位的方法也非常多,但是笔者的原则就是什么简单用什么,因此这里介绍几种比较简单实用的保留小数位的方法: 方法一:fo ...

  4. python中定义一个空的字符串_04python—15种字符串操作

    <python小白入门系列教程> 专栏 • 第04篇 字符串是 字符的序列 .字符串基本上就是一组单词.我几乎可以保证你在每个Python程序中都要用到字符串,所以请特别留心下面这部分的内 ...

  5. Python学习,python中参数传递的方法,你知道几种

    Python中函数传递参数的形式主要有以下五种,分别为位置传递,关键字传递,默认值传递,不定参数传递(包裹传递)和解包裹传递. 1.位置传递实例: def fun(a,b,c) return a+b+ ...

  6. python读文件路径-在Python中按路径读取数据文件的几种方式

    我们知道,写Python代码的时候,如果一个包(package)里面的一个模块要导入另一个模块,那么我们可以使用相对导入: 假设当前代码结构如下图所示: img 其中test_1是一个包,在util. ...

  7. python syntaxerror怎么解决-python中出现invalid syntax报错的几种原因

    这篇文章旨为刚接触python不久的朋友,提供一点帮助,请在检查代码没有主要问题时再看是否存在以下问题. 一般来说,写完代码运行时,如果代码中有错误,解释器会提示错误信息,按照提示信息,一般很快可以找 ...

  8. python中的请求方法_http协议的9种请求方法

    http协议的9种请求方法 在http/1.1协议中,定义了8种访问指定资源的方法,他们分别为 OPTIONS GET HEAD POST PUT PATCH DELETE TRACE CONNECT ...

  9. python中求质数_python求质数的3种方法

    本文为大家分享了多种方法求质数python实现代码,供大家参考,具体内容如下 题目要求是求所有小于n的质数的个数. 求质数方法1: 穷举法: 根据定义循环判断该数除以比他小的每个自然数(大于1),如果 ...

  10. python中循环语句只有for和while两种_Python循环语句之while,for语句详解

    下面为大家分享一篇Python 循环语句之 while,for语句详解,具有很好的参考价值,希望对大家有所帮助.一起过来看看吧 Python中有两种循环,分别为:for循环和while循环. for循 ...

最新文章

  1. 2022-2028年中国车载天线行业市场前瞻与投资战略规划分析报告
  2. Redis数据库简介与(CentOS 7)编译安装
  3. 网站关键词如何布局更有利于关键词排名提升?
  4. 13.while循环
  5. 基于机器学习的捡球机器人设计与实现(探索)第3篇——opencv基础知识学习(2019-02-02)
  6. 征战蓝桥 —— 2013年第四届 —— C/C++A组第6题——逆波兰表达式
  7. 计算机文化基础分析总结,《计算机文化基础实训》教学方案设计与课题分析总结.doc...
  8. python中将整数转化为八进制的函数,Python进制转化
  9. linux无效内存访问,x86_64 Linux 3.0:无效的内存地址
  10. sklearn.preprocessing.Imputer
  11. 在别人客户端上修改,来匹配测试自己的服务端
  12. 已有一个名为“frmadd”的组件。组件的名称必须是唯一的,而且名称必须不区分大小
  13. 1004. 成绩排名 (20)
  14. python贪吃蛇源码下载_Python贪吃蛇源代码
  15. C语言程序设计基础(02)—— Visual Studio Code 软件安装与使用
  16. 【AI视野·今日Robot 机器人论文速览 第二十三期】Tue, 28 Sep 2021
  17. Win7 安装VS2005时 Dexplore安装失败的解决方法
  18. 注册一个域名需要多少钱_域名注册需要多少钱?购买一个域名需要多少钱
  19. java tea collection_Javaの集合学习
  20. 北森招股书:赛道优势凸显,一体化+中大客户是加分项

热门文章

  1. 任务调度(三)——Timer的替代品ScheduledExecutorService简单介绍
  2. 解读2015之大数据篇:大数据的黄金时代
  3. MAC SSH密钥登陆
  4. 给商品评分效果,CSS技巧
  5. 我的第一个keil工具写的汇编
  6. 【rqnoj】 1 明明的随机数
  7. 在Intellij IDEA里面配置Tomcat和Websphere Application Server
  8. bzoj4144【AMPPZ2014】Petrol
  9. Nginx安装,目录结构与配置文件详解
  10. Perl读写Excel简单操作