Python 语法 之 try...except...finally

Python 语法 之 try...except...finally

try 语句为一组语句指定了 异常处理清除操作的代码

语法

语法说明

  • stmt: 表示为statement的简写
  • ::: 表示为一个块, 一个空间
  • |:表示任选其一, 要么是 try1_stmt, 要么是try2_stmt
  • "": 表示是固定写法, 包括关键字特殊符号
  • []: 方括号中内容表示是可选的, 可以有,也可以没有
  • suite: 套件, 即代码块
try_stmt  ::=  try1_stmt | try2_stmt
try1_stmt ::=  "try" ":" suite
               ("except" [expression ["as" identifier]] ":" suite)+
               ["else" ":" suite]
               ["finally" ":" suite]
try2_stmt ::=  "try" ":" suite
               "finally" ":" suite

语法规则:

tryexceptfinally必须成对出现

格式 必须 可选
try1_stmt try+except else+finally
try2_stmt try+finally

执行

执行流程:

  • 有异常: try -> except -> finally
  • 无异常: try -> else -> finally

无异常执行流程

try suite中没有异常时, except子句不会执行

try:
    print('try statement')
except:
    print('except statement')

输出: 
try statement

如果提供了else子句, 则会跳转执行else子句

try:
    print('try statement')
except:
    print('except statement')
else:
    print('else statement')
    
输出:
 try statement
 else statement

如果还提供了finally子句, 则再执行finally子句

try:
    print('try statement')
except:
    print('except statement')
else:
    print('else statement')
finally:
    print('finally statement')
    
输出:
try statement
else statement
finally statement

注意: 如果提供了else子句, 且其中没有returncontinuebreak语句执行, 且没有异常抛出的情况下, 才会执行else子句

try suite中有执行return的情况下, 不会执行else子句:

def funcR():
    try:
        print('try statement')
        return None
    except:
        print('except statement')
    else:
        print('else statement')
print('return', funcR())

输出:
try statement
return None

try suite中有执行break的情况下, 不会执行else子句:

def funcB():
    for x in range(5):
        try:
            print('try statement', x)
            if x == 2:
                break
        except:
            print('except statement')
        else:
            print('else statement')
funcB()

输出:
try statement 0
else statement
try statement 1
else statement
try statement 2

try suite中有执行continue的情况下, 不会执行else子句:

def funcC():
    for x in range(5):
        try:
            print('try statement', x)
            if x >= 2:
                continue
        except:
            print('except statement')
        else:
            print('else statement')
funcC()
输出为:
try statement 0
else statement
try statement 1
else statement
try statement 2
try statement 3
try statement 4

有异常执行流程

try suite中发生异常时, try suite中异常位置之后的代码不会执行, 并开始依次检查except子句, 如果匹配, 则执行该except子句, 如果提供了else子句, 则不会执行else子句, 如果还提供了 finally子句, 则再执行finally子句

try:
    print('try statement')
    1/0
    print('try statement after except')
except ZeroDivisionError as e:
    print('except statement: ZeroDivisionError:', e)
except (AttributeError, ValueError) as e:
    print('except statement: AttributeError or ValueError:',  e)
except:
    print('except statement')
else:
    print('else statement')
finally:
    print('finally statement')
    
输出:
try statement
except statement: ZeroDivisionError: division by zero
finally statement

try suite发生异常时, 会查找匹配except子句. 如果except后面没有表达式, 则默认匹配所有异常, 如果有多个带表达式except子句, 则要注意:

  • 表达式 必须是兼容的: 兼容指的的是 表达式必须是BaseException的子类, 或是其包装成的元组, 例如ValueErrorIndexError、(ValueError, IndexError), 否则会引起新的异常
  • except: 放在最下面: 如果有不带表达式exception子句, 则必须放在带表达式exception子句最下面

捕获异常有两种方式:

  1. as target:

    使用as target语句, 来将except中的表达式赋给target, 从而可以在except 代码块中使用, 例如: except ValueError as error, error就是捕获到的异常对象, 但要注意该对象仅在当前except代码块中可用, 在结尾时会被删除.

  1. sys.exc_info():

    发生异常时, 在except子句执行前, python会将异常信息的细节存储到sys模块, 可以通过sys.exc_info()来访问.

    sys.exc_info()会返回一个三元元组, 包含(异常类对象, 异常对象, traceback对象), 当except子句执行完后, sys.exc_info()存储的值会回复到之前的值, 如果在finally子句中获取, 会获取不到这个异常信息

    try:
         print('try statement')
         1/0
         print('try statement after except')
    except:
        print('except statement', sys.exc_info())
    else:
        print('else statement')
    finally:
        print('finally statement', sys.exc_info())
    输出:
    try statement
    (, ZeroDivisionError('division by zero',), )
    (None, None, None)
    

参考文档: python 官方文档 the-try-statement

你可能感兴趣的:(Python 语法 之 try...except...finally)