with 都帮我们做了点啥?finally是什么?

  • with
with open(file='HelloWorld', mode='r')as f:
    print(f.read())
  • 没用with
import traceback

f = open(file='HelloWorld', mode='w')
try:
    f.write('world: go away')
    
except:
    print(traceback.format_exc())
    
finally:
    f.close()

打开文件在进行读写的时候可能会出现一些异常状况,按 f.open 的写法,是需要try、except、finally,做异常判断的,并且文件是否能执行,都要执行 finally f.close() 关闭文件

with 方法帮我们实现了 finally 中 f.close



finally是什么?

无论 try语句中是否抛出异常,finally中的语句一定会被执行。

f = open(file='HelloWorld', mode='w')
try:
    f.write('world: go away')
	print(1)
finally:
    f.close()
    print(2)

不论 try 中写文件的过程中是否有异常,finally 中关闭文件的操作一定会执行。

# 打印结果
1
2

那执行的顺序是什么样的呢?
def func1():
   try:
       return 1
   finally:
       return 2
 
def func2():
   try:
       raise ValueError()
   except:
       return 1
   finally:
       return 3
 
print(func1())
print(func2())
# 执行结果
2  "func1"
3  "func2"

上个例子中可以看到

  • func1的 try 的 return 是没有返回结果的
  • func2的 except 的 return 是没有返回结果的

python 官网中 对 finally 有这样的解释:

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.

译文:

无论是否发生异常,finally子句总是在离开try语句之前执行。如果在try子句中发生了异常,并且没有被except子句处理(或者在except或else子句中发生了异常),则在finally子句执行后重新引发该异常。当try语句的任何其他子句通过break、continue或return语句离开时,也会“在离开时”执行finally子句。

重点部分用粗体标出了,翻成是 try 块中包含 break、continue 或者 return 语句的,在离开 try 块之前,finally 中的语句也会被执行。

上面的例子:
  • func1() ,在try块return之前,会执行finally中的语句,try中的return被忽略了,最终返回的值是finally中return的值。

  • func2() ,try块中抛出异常,被except捕获,在except块return之前,执行finally中的语句,except中的return被忽略,最终返回的值是finally中return的值。

def func1():
    try:
        print('func1-try: return 1')
        return 1
    finally:
        print('func1-finally: return 2')
        return 2


def func2():
    try:
        print('func2-try: raise error')
        raise ValueError()

    except:
        print('func2-except: return 1')
        return 1
    finally:
        print('func2-finally: return 3')
        return 3


print(func1())
print(func2())

# 打印结果

func1-try: return 1
func1-finally: return 2
2

func2-try: raise error
func2-except: return 1
func2-finally: return 3
3

这样就方便理解多了

当 try 监听的和 except 执行的不是同一个异常时 ?
def func():
   try:
       print 'try: raise error'
       raise ValueError()
   except IndexError:
       print 'except: IndexError'
       return 1
   finally:
       print 'finally'
       return 3
 
print func()
# 打印结果

in func2 try: raise error
finally
3
  • try 中抛出的异常是 ValueError 类型的,而 except 中定位的是 IndexError 类型的,try 中抛出的异常没有被捕获到,所以 except 中的语句没有被执行,但不论异常有没有被捕获,finally 还是会执行,最终函数返回了 finally 中的返回值 3。

  • try 中抛出的异常没有被捕获到,按理说当 finally 执行完毕后,应该被再次抛出,但 finally 里执行了 return,导致异常被丢失。

可以看到在 finally 中使用 return 会导致很多问题。实际应用中,不推荐在 finally 中使用 return 返回。


来源:强哥 公众号:Python与数据分析 链接:

https://mp.weixin.qq.com/s/6jBvyl1YoVBRyVQCdC67Sg

finally介绍转自:https://blog.csdn.net/gyniu/article/details/80345160

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值