if 一切正常:
#业务实现代码
else:
alert 输入不合法
goto retry
try:
#业务实现代码
...
except (Error1, Error2, ...) as e:
alert 输入不合法
goto retry
inputStr = input("请输入您下棋的坐标,应以x,y的格式:\n") while inputStr != None : try: # 将用户输入的字符串以逗号(,)作为分隔符,分隔成2个字符串 x_str, y_str = inputStr.split(sep = ",") # 如果要下棋的点不为空 if board[int(y_str) - 1][int(x_str) - 1] != "╋": inputStr = input("您输入的坐标点已有棋子了,请重新输入\n") continue # 把对应的列表元素赋为"●"。 board[int(y_str) - 1][int(x_str) - 1] = "●" except Exception: inputStr = input("您输入的坐标不合法,请重新输入,下棋坐标应以x,y的格式\n") continue ...上面程序把处理用户输入字符串的代码都放在 try 块里执行,只要用户输入的字符串不是有效的坐标值(包括字母不能正确解析,没有逗号不能正确解析,解析出来的坐标引起数组越界……),系统就将引发一个异常对象,并把这个异常对象交给对应的 except 块处理。
图 1 Python 异常捕获流程示意图
图 2 Python 的常见异常类之间的继承关系
import sys try: a = int(sys.argv[1]) b = int(sys.argv[2]) c = a / b print("您输入的两个数相除的结果是:", c ) except IndexError: print("索引错误:运行程序时输入的参数个数不够") except ValueError: print("数值错误:程序只能接收整数参数") except ArithmeticError: print("算术错误") except Exception: print("未知异常")上面程序,导入了 sys 模块,并通过 sys 模块的 argv 列表来获取运行 Python 程序时提供的参数。其中 sys.argv[0] 通常代表正在运行的 Python 程序名,sys.argv[1] 代表运行程序所提供的第一个参数,sys.argv[2] 代表运行程序所提供的第二个参数……依此类推。
Python 用 import 例来导入模块,关于模块和导入模块会在后续章节进行详细讲解。
上面程序针对 IndexError、ValueError、ArithmeticError 类型的异常,提供了专门的异常处理逻辑。该程序运行时的异常处理逻辑可能有如下几种情形:虽然 Python 语法没有要求,但在实际编程时一定要记住先捕获小异常,再捕获大异常。
import sys try: a = int(sys.argv[1]) b = int(sys.argv[2]) c = a / b print("您输入的两个数相除的结果是:", c ) except (IndexError, ValueError, ArithmeticError): print("程序发生了数组越界、数字格式异常、算术异常之一") except: print("未知异常")上面程序中第 7 行代码使用了(IndexError, ValueError, ArithmeticError)来指定所捕获的异常类型,这就表明该 except 块可以同时捕获这三种类型的异常。
def foo(): try: fis = open("a.txt"); except Exception as e: # 访问异常的错误编号和详细信息 print(e.args) # 访问异常的错误编号 print(e.errno) # 访问异常的详细信息 print(e.strerror) foo()从上面程序可以看出,如果要访问异常对象,只要在单个异常类或异常类元组(多异常捕获)之后使用 as 再加上异常变量即可。
在 Python 的早期版本中,直接在单个异常类或异常类元组(多异常捕获)之后添加异常变量,中间用逗号隔开即可。
上面程序调用了 Exception 对象的 args 属性(该属性相当于同时返回 errno 属性和 strerror 属性)访问异常的错误编号和详细信息。运行上面程序,会看到如下运行结果:
(2, 'No such file or directory')
2
No such file or directory
关于如何处理异常的传播轨迹信息,后续章节还有更详细的介绍,此处暂不详细讲解。
上面程序中使用 open() 方法来打开一个文件,用于读取磁盘文件的内容。关于该 open() 方法后续章节会做详细介绍。s = input('请输入除数:') try: result = 20 / int(s) print('20除以%s的结果是: %g' % (s , result)) except ValueError: print('值错误,您必须输入数值') except ArithmeticError: print('算术错误,您不能输入0') else: print('没有出现异常')上面程序为异常处理流程添加了 else 块,当程序中的 try 块没有出现异常时,程序就会执行 else 块。运行上面程序,如果用户输入导致程序中的 try 块出现了异常,则运行结果如下:
请输入除数:a
值错误,您必须输入数值
请输入除数:3
20 除以3 的结果是:6.66667
没有出现异常
def else_test(): s = input('请输入除数:') result = 20 / int(s) print('20除以%s的结果是: %g' % (s , result)) def right_main(): try: print('try块的代码,没有异常') except: print('程序出现异常') else: # 将else_test放在else块中 else_test() def wrong_main(): try: print('try块的代码,没有异常') # 将else_test放在try块代码的后面 else_test() except: print('程序出现异常') wrong_main() right_main()上面程序中定义了一个 else_test() 函数,该函数在运行时需要接收用户输入的参数,随着用户输入数据的不同可能导致异常。接下来程序定义了 right_main() 和 wrong_main() 两个函数,其中 right_main() 将 else_test() 函数放在 else 块内;而 wrong_main() 将 else_test() 函数放在 try 块的代码的后面。
try块的代码,没有异常
请输入除数:4
20除以4的结果是: 5
try块的代码,没有异常
请输入除数:4
20除以4的结果是: 5
try块的代码,没有异常
请输入除数:0
程序出现异常
try块的代码,没有异常
请输入除数:0
Traceback (most recent call last):
File "C:\Users\mengma\Desktop\1.py", line 21, in <module>
right_main()
File "C:\Users\mengma\Desktop\1.py", line 12, in right_main
else_test()
File "C:\Users\mengma\Desktop\1.py", line 3, in else_test
result = 20 / int(s)
ZeroDivisionError: division by zero
对比上面两个输出结果,不难发现,放在 else 块中的代码所引发的异常不会被 except 块捕获。
所以,如果希望某段代码的异常能被后面的 except 块捕获,那么就应该将这段代码放在 try 块的代码之后;如果希望某段代码的异常能向外传播(不被 except 块捕获),那么就应该将这段代码放在 else 块中。本文链接:http://task.lmcjl.com/news/17111.html