try语句的可选else子句的预期用途是什么?
else
块中的语句会在try
块的结尾处执行,如果没有异常出现的话。老实说,我从来没有发现需要使用它。所以,如果您有一个可能会引发使用
else
子句比向try
子句添加附加代码更好,因为它避免了意外捕获由try...except
语句保护的代码未引发的异常。
IOError
的方法,并且您想要捕获它引发的异常,但是在第一个操作成功后还有其他事情要做,而您不想从该操作中捕获IOError
,您可以编写类似以下内容的代码:try:
operation_that_can_throw_ioerror()
except IOError:
handle_the_exception_somehow()
else:
# we don't want to catch the IOError if it's raised
another_operation_that_can_throw_ioerror()
finally:
something_we_always_need_to_do()
operation_that_can_throw_ioerror
后面加上another_operation_that_can_throw_ioerror()
,那么except
会捕获第二个调用的错误。如果你把它放在整个try
块之后,它将总是被运行,但要等到finally
之后才运行。else
让你确保:
finally
块之前运行;IOError
都不会在这里被捕获。return
、continue
或 break
的存在。 - Antti Haapala -- Слава Україні使用else
命令的一个很大的原因是风格和可读性。通常,将可能引发异常的代码与处理它们的代码紧密相邻是个好主意。例如,请比较以下内容:
try:
from EasyDialogs import AskPassword
# 20 other lines
getpass = AskPassword
except ImportError:
getpass = default_getpass
和
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
else:
# 20 other lines
getpass = AskPassword
如果except
不能早期返回或重新抛出异常,第二种方法更好。 如果可能的话,我会这样写:
try:
from EasyDialogs import AskPassword
except ImportError:
getpass = default_getpass
return False # or throw Exception('something more descriptive')
# 20 other lines
getpass = AskPassword
注意: 此答案从最近发布的重复问题 这里 复制,因此有关"AskPassword"的所有内容都是基于那个问题。
try
语句的可选else
从句的预期用途是在没有异常被处理的情况下,提供更多代码运行的上下文。
这个上下文可以避免意外处理您没有预期的错误。
但重要的是要了解导致else
子句运行的精确条件,因为return
、continue
和break
语句可能会中断对else
的控制流。
如果没有异常并且没有被return
、continue
或break
语句中断,则else
语句将被执行。
如果控制流程离开
try
子句末尾,就会执行可选的else
子句。
(加粗部分是笔者添加的) 脚注如下:
*目前,控制流程在除了异常或执行
return
、continue
或break
语句的情况下会离开。
它至少需要一个前置的except
子句(请参见语法)。所以它真的不是"try-else",而是"try-except-else(-finally)",其中else
(和finally
)是可选的。
Python教程详细阐述了其预期用途:
try ... except语句有一个可选的else从句,当存在时,必须跟在所有except从句之后。对于必须在try从句不引发异常时执行的代码很有用。例如:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except OSError: print('cannot open', arg) else: print(arg, 'has', len(f.readlines()), 'lines') f.close()
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
else
和 try
代码块后的代码如果你处理了一个错误,else
块将不会被执行。例如:
def handle_error():
try:
raise RuntimeError('oops!')
except RuntimeError as error:
print('handled a RuntimeError, no big deal.')
else:
print('if this prints, we had no error!') # won't print!
print('And now we have left the try block!') # will print!
现在,
>>> handle_error()
handled a RuntimeError, no big deal.
And now we have left the try block!
else
子句比将其他代码添加到try
子句中更好,因为它避免了意外捕获未被try ... except
语句保护的代码引发的异常。” - starriettry:
this_should_raise_TypeError()
except TypeError:
pass
except:
assert False, "Raised the wrong exception type"
else:
assert False, "Didn't raise any exception"
try:
cs = x.cleanupSet
except AttributeError:
pass
else:
for v in cs:
v.cleanup()
你可能认为这个天真的代码没问题:
try:
for v in x.cleanupSet:
v.clenaup()
except AttributeError:
pass
如果有必要进行清理工作,并且即使发生异常也必须执行该清理工作,那么下面的方法非常有用:
try:
data = something_that_can_go_wrong()
except Exception as e: # yes, I know that's a bad way to do it...
handle_exception(e)
else:
do_stuff(data)
finally:
clean_up()
尽管你现在无法想到它的用途,但可以肯定地是必须有一种用途的。这里是一个缺乏想象力的示例:
有了else
:
a = [1,2,3]
try:
something = a[2]
except IndexError:
print("out of bounds")
else:
print(something)
没有else
:
try:
something = a[2]
except IndexError:
print("out of bounds")
if "something" in locals():
print(something)
如果没有错误抛出,这里定义了变量something
。您可以将其从try
块外移除,但是那样需要进行一些混乱的检测以确定变量是否已定义。
something = a[2]; print something
有什么问题? - S.Lottsomething = 'out of bound'
,这样 print(something)
就总是会输出正确的响应;-) - wovano在PEP 380中有一个很好的try-else
示例。基本上,它涉及在算法的不同部分中进行不同的异常处理。
大概是这样的:
try:
do_init_stuff()
except:
handle_init_suff_execption()
else:
try:
do_middle_stuff()
except:
handle_middle_stuff_exception()
这样可以让你在异常发生的位置更近的地方编写异常处理代码。
来自错误和异常 # 处理异常 - docs.python.org
The
try ... except
statement has an optionalelse
clause, which, when present, must follow all except clauses. It is useful for code that must be executed if the try clause does not raise an exception. For example:
for arg in sys.argv[1:]: try: f = open(arg, 'r') except IOError: print 'cannot open', arg else: print arg, 'has', len(f.readlines()), 'lines' f.close()
The use of the else clause is better than adding additional code to the try clause because it avoids accidentally catching an exception that wasn’t raised by the code being protected by the try ... except statement.
try:
statements # statements that can raise exceptions
except:
statements # statements that will be executed to handle exceptions
else:
statements # statements that will be executed if there is no exception
例子:
try:
age=int(input('Enter your age: '))
except:
print ('You have entered an invalid value.')
else:
if age <= 21:
print('You are not allowed to enter, you are too young.')
else:
print('Welcome, you are old enough.')
>>>
Enter your age: a
You have entered an invalid value.
>>> RESTART
>>>
Enter your age: 25
Welcome, you are old enough.
>>> RESTART
>>>
Enter your age: 13
You are not allowed to enter, you are too young.
>>>
来源: https://geek-university.com/python/the-try-except-else-statements/
try
语句用于捕获异常,except
子句用于处理异常。如果在 try
块中发生异常,那么该异常会被 except
子句捕获并处理。
else
子句是 try
和 except
子句之外的部分。如果没有发生任何异常,则 else
子句中的代码将被执行。
try/else
和for/else
中的else
所起的作用,我在这些情况下已经将其与noexcept
和nobreak
在心理上进行了关联。个人认为这种词汇的过载是一个非常不幸的现象,因为它会使阅读代码的人们想要知道“这个东西到底是做什么的?”通常,一个标志、一个continue
或break
语句可以用更少的额外行数来传达我想表达的意思,但当然也更清晰(如果这个问题的受欢迎程度是任何迹象的话)。 - Michael Ekoka