好冷的Python~return遇上try…except…finally还会return吗

原文链接:http://www.juzicode.com/archives/5232

先来个开胃菜看一个函数,这个函数检查输入的数值是正数、负数或是否为0,并返回相应的数值1、-1或者0:

#VX公众号:桔子code / juzicode.com
def func(num):
    if num > 0:
        print(num,'是一个正数')
        return 1
    elif num < 0:
        print(num,'是一个负数')
        return -1
    else:
        print(num,'非正非负')
        return 0
        
res = func(5)
print('res:',res)
res = func(-5)
print('res:',res)
res = func(0)
print('res:',res)

运行结果:

5 是一个正数
res: 1
-5 是一个负数
res: -1
0 非正非负
res: 0

从运行结果看,当数值为正数时,在func()函数的if语句中因为return语句退出了,return语句有“高”优先级,它会阻止后续代码的执行。

接下来再看一个关于异常的例子:

#VX公众号:桔子code / juzicode.com
s = 'juzicode.com'
p = s.index('code')
print('code起始位置:',p)
p = s.index('CODE')
print('CODE起始位置:',p)

运行结果:

code起始位置: 4
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-14d4890092f9> in <module>
      3 p = s.index('code')
      4 print('code起始位置:',p)
----> 5 p = s.index('CODE')
      6 print('CODE起始位置:',p)

ValueError: substring not found

这个例子中用到了字符串的index()方法,如果要查找的子串在字符串中,则返回子串的起始位置,如果子串不在字符串中则会抛异常。

通常在用户程序中,我们要用try…except语句来捕获异常,以免出现上述这种因为异常导致程序中断运行的情况:

#VX公众号:桔子code / juzicode.com
def find_sub(s,sub):
    try:
        p = s.index(sub)
        print('p=',p)
        return p
    except:
        print('执行到: except')
        return -1

s = 'juzicode.com'
sub = 'code'
print(sub,'起始位置:',find_sub(s,sub))

sub = 'CODE'
print(sub,'起始位置:',find_sub(s,sub))

运行结果:

p= 4
code 起始位置: 4
执行到: except
CODE 起始位置: -1

try…except语句还有一个变种语句try…except…finally,finally语句不管在什么情况下都会执行到。从最开始的例子中我们看到return语句有很高的优先级,如果我们在try和except中增加了return语句,finally还能执行吗?

#VX公众号:桔子code / juzicode.com

def find_sub(s,sub):
    try:
        p = s.index(sub)
        print('p=',p)
        return p
    except:
        print('执行到: except')
        return -1
    finally:
        print('执行到: finally')
        return None
    
s = 'juzicode.com'
sub = 'code'
print(sub,'起始位置:',find_sub(s,sub))

sub = 'CODE'
print(sub,'起始位置:',find_sub(s,sub))

运行结果:

p= 4
执行到: finally
code 起始位置: None
执行到: except
执行到: finally
CODE 起始位置: None

从这个例子我们可以看到在能找到子串和不能找到子串的情况下,按照常理分别应该返回子串的实际起始位置或者返回-1,但是最后实际上都进入到了finnally语句返回了None。在这里finnally语句反而比try和except里的return语句有更高的优先级它会中断try和except里的return语句的执行,而且finally语句里如果有return会优先得到执行,从而导致try或者except里的return被阻断了!

我们知道一个函数如果没有显式地调用return语句实际返回的是None,这里如果把finally里的return语句去掉,是不是也会优先返回None呢?

#VX公众号:桔子code / juzicode.com

def find_sub(s,sub):
    try:
        p = s.index(sub)
        print('p=',p)
        return p
    except:
        print('执行到: except')
        return -1
    finally:
        print('执行到: finally')
        #return None
    
s = 'juzicode.com'
sub = 'code'
print(sub,'起始位置:',find_sub(s,sub))

sub = 'CODE'
print(sub,'起始位置:',find_sub(s,sub))

运行结果:

p= 4
执行到: finally
code 起始位置: 4
执行到: except
执行到: finally
CODE 起始位置: -1

同样地,finally里虽然没有return语句,但是finally后的语句仍然得到了执行。​但是因为finally语句里没有return语句,它执行完之后并不是默认地返回None,而是又回到了原来的try或者except中执行return语句了!

千言万语不胜一图,最后的总结在这里:

原文链接:http://www.juzicode.com/archives/5232

扩展阅读:

  1.  Python基础教程6–函数
  2.  Python进阶教程m6–异常

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注