一、实验目的
- 断言
- NameError
- TypeError
- 异常处理(try..except)
- 异常抛出(raise)
- finally 子句
二、知识要点
1.断言
Python assert(断言)用于判断一个表达式,在表达式条件为 false 的时候触发异常。断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况,语法格式为:
assert expression
例如我们的代码只能在windows系统下运行,可以先判断当前系统是否符合条件:
import sys
assert ('linux' in sys.platform), '错误'
print("hello")
会输出:
Traceback (most recent call last):
File "F:/Python/10/eg 10-1.py", line 5, in <module>
assert ('linux' in sys.platform), '错误'
AssertionError: 错误
Process finished with exit code 1
当我们将linux
更改为win32
就会输出hello
2.错误和异常
在程序执行过程中发生的任何错误都是异常。每个异常显示一些相关的错误信息,比如我们在 Python3 中使用 Python2 独有的语法就会发生SyntaxError
:
print 'hello'
输出为:
File "F:/Python/10/eg 10-1.py", line 11
print 'hello'
^
SyntaxError: Missing parentheses in call to 'print'. Did you mean print('hello')?
而如果我们多打了一个空格:
print('hello')
就会出现IndentationError
File "F:/Python/10/eg 10-1.py", line 12
print('hello')
^
IndentationError: unexpected indent
Process finished with exit code 1
接下来将介绍几种常见的异常:
2.1 NameError
当访问一个未定义的变量则会发生 NameError
,例如:print(a)
会输出:
Traceback (most recent call last):
File "F:/Python/10/eg 10-1.py", line 15, in <module>
print(a)
NameError: name 'a' is not defined
2.2 ZeroDivisionError
当把0
作为除数则会发生 ZeroDivisionError
,例如:print(1/0)
会输出:
Traceback (most recent call last):
File "F:/Python/10/eg 10-1.py", line 18, in <module>
print(1/0)
ZeroDivisionError: division by zero
2.3 TyprError
当操作或函数应用于不适当类型的对象时引发TyprError
,较为常见的是字符串与整数加法,例如:print('1'+1)
会输出:
Traceback (most recent call last):
File "F:/Python/10/eg 10-1.py", line 21, in <module>
print('1'+1)
TypeError: can only concatenate str (not "int") to str
标准异常:https://www.runoob.com/python/python-exceptions.html
3.异常处理
异常处理我将通过一个例子来解释上图的流程:
a = 0
while a != -1:
try:
a = int(input("输入一个数字:"))
if a == -1:
break
except ValueError:
print("输入类型有误")
else:
print(1 + a)
print("输入类型无误")
finally:
print("结束")
print("循环结束")
我们分别输入1
和a
,最后输入-1
结束,输出如下:
输入一个数字:1
2
输入类型无误
结束
输入一个数字:a
输入类型有误
结束
输入一个数字:-1
结束
循环结束
这个过程是这样的:
- 如果我们输入一个数字
-1
,程序停止循环,程序等价为:
while a != -1:
try:
a = int(input("输入一个数字:"))
if a == -1:
break
finally:
print("结束")
print("循环结束")
注意:finally
只要执行了try
不管有没有异常都会执行。在真实场景的应用程序中,finally
子句用于释放外部资源(文件或网络连接之类的),无论它们的使用过程中是否出错。
- 如果我们输入一个字母
‘a’
,程序异常,程序等价为:
while a != -1:
try:
a = int(input("输入一个数字:"))
if a == -1:
break
except ValueError:
print("输入类型有误")
finally:
print("结束")
print("循环结束")
即程序在try
中的语句中出现了异常,会在except
中匹配对应的异常类型,如果未匹配则会终止程序,如果匹配上对应的异常类型会执行对应except
下的语句,如果语句中有fially
,在执行完except
中的语句会执行fianlly
中的语句。
- 如果我们输入一个整数
1
,程序无异常,程序等价为:
while a != -1:
try:
a = int(input("输入一个数字:"))
if a == -1:
break
else:
print(1 + a)
print("输入类型无误")
finally:
print("结束")
print("循环结束")
即程序通过try
语句检测之后没有异常,如果是try-except
格式,在没有异常的情况下会直接跳出try-except
程序块,继续向下执行;如果是try-except-else
格式,在没有异常的情况下会进入else
语句中的代码;如果是try-except-else-finally
格式,在执行完else
语句会执行finally
语句中的内容。
4.抛出异常
使用raise语句主动抛出异常的意思是开发者可以自己制造程序异常,这里的程序异常不是指发生了内存溢出、列表越界访问等系统异常,而是指程序在执行过程中,发生了用户输入的数据与要求数据不符、用户操作错误等问题,这些问题都需要程序进行处理并给出相应的提示。处理这些问题多使用判断语句,在判断语句体内进行相应的问题处理,如果处理问题的语句过多,就会导致代码复杂化,代码结构不够清晰。在这种情况下,可以使用raise语句主动抛出异常,由异常处理语句块进行处理。例如:
try:
print("请输入登录账号:")
username = input(">>:")
if username != "zhe":
raise Exception("用户名输入错误")
print("请输入密码:")
psw = input(">>:")
if psw != "123456":
raise Exception("密码输入错误")
except Exception as e:
print(e)
在上述代码中,当我们输入用户名不是zhe
时会主动抛出异常用户名输入错误
而此时except
语句会捕获异常并输出,而如果我们用户名无误,程序会继续向下进行,在密码输入处如果错误会抛出密码输入错误
异常,由except
捕获之后输出,如果一直无误,程序执行完之后跳出try-except
语句。执行下一程序块。
三、实验内容
1.玩转函数
本次挑战中我们将实现一个程序,将分钟转为小时和分钟。在 MinutesToHours.py 文件中实现一个函数 Hours()
,将用户输入的 分钟数
转化为 小时数和分钟数
,并要求小时数尽量大。将结果以 XX H, XX M
的形式打印出来。
输入:80
输出:1 H,20 M
注意:
- 代码中不要使用
input()
函数。 - 如果用户输入的是一个负值,程序需要
raise
来抛出ValueError
异常。 -
Hours()
函数调用的时候,需要使用try...except
处理异常。获取异常后,在屏幕上打印出Parameter Error
提示用户输入的值有误。
- 代码:
import sys
def Hours(minute):
if minute < 0:
raise ValueError("负值")
else:
print("{} H,{} M".format(int(minute / 60), minute % 60))
try:
Hours(int(sys.argv[1]))
except ValueError:
print("Parameter Error")
- 控制台的输出为:
(venv) F:\Python\10>python hour.py 70
1 H,10 M
有关sys.argv[]
的解释
在sys.argv[value]
中对于输入的内容实际上保存为了一个列表,列表的第一个元素即为脚本,例如我们写一个输出脚本print_f.py
,脚本中的代码如下:
import sys
a = sys.argv[0]
print(a)
我们通过控制台在根目录运行,输入:python print_f
,敲击回车,会输出print_f
此时我们更改一下脚本中的代码为:
import sys
a = sys.argv[1]
print(a)
我们再通过控制台在根目录输入:python print_f hello
敲击回车会输出hello
我们再更改一次代码:
import sys
a = sys.argv[2:]
print(a)
在控制台中输入:python print_f a b c d e
敲击回车输出的为:['b', 'c', 'd', 'e']
。
通过上面的例子我们容易理解sys.argv
的用法。
四、实验结果
无
网友评论