pythontryexceptfinally_Python中try/except/else/finally的执行机制

最近经常使用到try/except/else/finally全部子句,对于执行顺序不是很熟悉,这里作一下记录。

不含return的情况

一般情况try:

print 'try'

except:

print 'except'

else:

print 'else'

finally:

print 'finally'

output:

try

else

finally

try子句异常try:

print 'try'/0

except:

print 'except'

else:

print 'else'

finally:

print 'finally'

output:

except

finally

try/except子句同时异常try:

print 'try'/0

except:

print 'except'/0

else:

print 'else'

finally:

print 'finally'

output:

finally

Traceback (most recent call last):

File "E:\tmp\test.py", line 4, in

print 'except'/0

TypeError: unsupported operand type(s) for /: 'str' and 'int'

else子句异常try:

print 'try'

except:

print 'except'

else:

print 'else'/0

finally:

print 'finally'

output:

try

finally

Traceback (most recent call last):

File "E:\tmp\test.py", line 12, in

t()

File "E:\tmp\test.py", line 7, in t

print 'else'/0

TypeError: unsupported operand type(s) for /: 'str' and 'int'

finally子句异常try:

print 'try'

except:

print 'except'

else:

print 'else'

finally:

print 'finally'/0

output:

try

else

Traceback (most recent call last):

File "E:\tmp\test.py", line 11, in

t()

File "E:\tmp\test.py", line 9, in t

print 'finally'/0

TypeError: unsupported operand type(s) for /: 'str' and 'int'

总结finally子句总会执行

除了try子句,其他子句中的异常都会抛出

包含return的情况

众所周知,return会直接跳出函数,那么它和异常机制的优先级如何呢?

try子句returndef t():

try:

print 'try'

return

except:

print 'except'

else:

print 'else'

finally:

print 'finally'

t()

output:

try

finally

else子句没有执行!finally子句仍然执行!

finally子句returndef t():

try:

print 'try'/0

return 0

except:

print 'except'/0

return 1

else:

print 'else'

return 2

finally:

print 'finally'

return 3

print t()

output:

finally

3

函数的返回值是3,而不是try子句中设置的0,而且except子句的异常不见了。但是如果注释掉finally子句的return,就可以看见except中抛出的异常。

def t():

try:

print 'try'/0

return 0

except:

print 'except'/0

return 1

else:

print 'else'

return 2

finally:

print 'finally'

# return 3

print t()

output:

finally

Traceback (most recent call last):

File "E:\tmp\test.py", line 15, in

print t()

File "E:\tmp\test.py", line 6, in t

print 'except'/0

TypeError: unsupported operand type(s) for /: 'str' and 'int'

这是为什么呢?其实官方文档里有讲:

A finally clause is always executed before leaving the try statement, whether an exception has occurred or not. When an exception has occurred in the try clause and has not been handled by an except clause (or it has occurred in a except or else clause), it is re-raised after the finally clause has been executed. The finally clause is also executed “on the way out” when any other clause of the try statement is left via a break, continue or return statement.

也就是说except、esle子句中的异常在finally子句执行之后才会抛出,但是finally直接return了,所以我们就看不到异常了,而且会覆盖本身的return值。这种用法显然是不符合初衷的,所以不建议在finally语句中使用return、break、continue这些跳出的语句,应仅用作资源释放操作,否则会出现意想不到的结果。

总结执行顺序 finally > return > else

finally的return会抑制其他子句异常抛出,不建议使用

一个例子def example(id):

db = get_db()

try:

with db.cursor() as cursor:

sql = '''update xxxx

set yyyy = yyyy + 1

where id = %s'''

cursor.execute(sql, (id,))

db.commit()

except Exception, e:

app.logger.error(e, exc_info=True)

db.rollback()

else:

# do sth else

return True

finally:

db.close()

注意return的位置和finally子句的用法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值