Python零基础速成班-第6讲-Python异常处理Exception,try&except,raise,assert,输入模块pyinputplus
学习目标
1、异常处理Exception:try/except 2、raise抛出错误 3、assert断言 4、输入模块pyinputplus 5、前期内容补充 6、课后作业(4必做1挑战)
友情提示:将下文中代码拷贝到JupyterNotebook中直接执行即可,部分代码需要连续执行。
1、异常处理Exception
异常处理对于程序调试和监控非常重要,可以有助于快速定位错误的位置和类型。Python获取异常(Exception)信息一般采用try/except的语句结构。
1.1 try/except
try…except…else…finally流程图:
try: 此处是需要检测的代码 except: 此处是try模块代码出现异常后需要执行的代码 else: 如果try不报错,则执行该处代码,和except模块是互斥关系(本讲不介绍else语法) finally: 此处是无论如何都要执行的代码
我们定义一个除法函数divfun,被除数42,除数为变量divideBy,依次执行除数为2、0、1,当执行除数为0时,有异常报错"division by zero",程序终止。
def divfun(divideBy):
return 42 / divideBy
print(divfun(2))
print(divfun(0))
print(divfun(1))
21.0
---------------------------------------------------------------------------
ZeroDivisionError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/1792200966.py in <module>
3
4 print(divfun(2))
----> 5 print(divfun(0))
6 print(divfun(1))
~\AppData\Local\Temp/ipykernel_13696/1792200966.py in divfun(divideBy)
1 def divfun(divideBy):
----> 2 return 42 / divideBy
3
4 print(divfun(2))
5 print(divfun(0))
ZeroDivisionError: division by zero
使用try/except捕获异常,将异常信息打印出来,这样哪怕发生异常,程序也不会终止,而是继续执行下去。
def difvfun1(divideBy):
try:
return 42 / divideBy
except ZeroDivisionError:
print('Error: Invalid argument.')
print(difvfun1(2))
print(difvfun1(0))
print(difvfun1(1))
21.0
Error: Invalid argument.
None
42.0
1.2 try函数、try方法、finally语法
1.2.1 try函数如何工作?
当try下面的语句运行后,碰到异常的时候,运行except下面的语句,最后运行finaly下面的语句,finaly语句一般做些资源释放的工作,比如关闭打开的文件等。
下例中,listfunc(2)正常运行,listfunc(11)则会抛出"list index out of range"错误,程序终止,listfunc(4)不会运行。
def listfunc(index):
list1 = [i for i in range(10)]
print(list1[index])
try:
listfunc(2)
listfunc(11)
listfunc(4)
except Exception as ex:
print(ex.args)
2
('list index out of range',)
1.2.2 try方法
一般放置于Function函数内部,程序可多次调用函数,如果某一函数执行有错则会抛出错误信息,后续函数执行不会终止。
def listfunc(index):
list1 = [i for i in range(10)]
try:
print(list1[index])
except Exception as ex:
print(ex.args)
listfunc(2)
listfunc(11)
listfunc(4)
2
('list index out of range',)
4
1.2.3 加入finally语法
finally配合try except使用,即无论异常是否产生都要执行,比如文件关闭,释放锁,把数据库连接返还给连接池等资源释放工作,注意:finally是可选的选项。
def spam(test,a):
try:
return test[1]/a
except (IndexError, ZeroDivisionError):
print('Error: someting wrong')
finally:
print("over")
test1 = [1,2,3,4]
spam(test1,0)
Error: someting wrong
over
1.2.4 except报错信息文本常用输出方法
①直接print输出,可自定义错误文本。
try:
5 / 0
except:
print("错误: 除数不能为0")
错误: 除数不能为0
②使用ex.args输出错误文本信息。
try:
5 / 0
except Exception as ex:
print(ex.args)
('division by zero',)
③使用Python内置对象解释器函数repr(ex)输出错误类型和错误文本信息。
下例中repr既输出错误类型"ZeroDivisionError" 也输出错误文本信息"division by zero"
try:
5 / 0
except Exception as ex:
print(repr(ex))
ZeroDivisionError('division by zero')
2、raise抛出错误
在Debugging调式模式中,我们常用raise语句引发异常,抛出错误。
Python raise语句由以下内容组成: 1.raise关键字 2.函数、try/except等途径调用raise抛出Exception 3.抛出一段有用的错误信息方便识别
如果没有涉及引发异常raise语句的try和except语句,程序只是崩溃并显示异常的错误消息。
raise Exception('This is the error message.')
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/1171522555.py in <module>
----> 1 raise Exception('This is the error message.')
Exception: This is the error message.
抛出一段有用的错误信息方便识别,可自定义错误信息
a= input("请输入一个数字:\n")
if(not a.isdigit()):
raise Exception("必须是数字")
请输入一个数字:
a
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/719696018.py in <module>
1 a= input("请输入一个数字:\n")
2 if(not a.isdigit()):
----> 3 raise Exception("必须是数字")
Exception: 必须是数字
raise抛出错误类型ValueError,错误文本"必须是数字",except捕获错误ValueError,repr输出类型和错误文本信息
try:
a = input("输入一个数字:\n")
if(not a.isdigit()):
raise ValueError("必须是数字")
except ValueError as e:
print("引发异常:",repr(e))
输入一个数字:
b
引发异常: ValueError('必须是数字')
函数直接抛出自定义错误,可看到错误被函数调用顺序
def test1():
test2()
def test2():
raise Exception('This is the error message.')
test1()
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/160679621.py in <module>
5 raise Exception('This is the error message.')
6
----> 7 test1()
~\AppData\Local\Temp/ipykernel_13696/160679621.py in test1()
1 def test1():
----> 2 test2()
3
4 def test2():
5 raise Exception('This is the error message.')
~\AppData\Local\Temp/ipykernel_13696/160679621.py in test2()
3
4 def test2():
----> 5 raise Exception('This is the error message.')
6
7 test1()
Exception: This is the error message.
3、Assert 断言,确保,认定
断言是一种健全的检查,以确保您的代码没有做明显错误的事情。
这些健全性检查由assert语句执行。如果健全性检查失败,则会引发AssertionError异常。
Python assert语句由以下内容组成: 1.assert关键字 2.条件(即计算结果为True或False的表达式) 3.条件为False时执行的语句
我们定义断言条件a>b 和 a>c,当不满足条件时候,则抛出AssertionError异常。
a = 2
b = 1
c = 3
assert a>b
assert a>c
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/3309886585.py in <module>
3 c = 3
4 assert a>b
----> 5 assert a>c
AssertionError:
ages = [26, 57, 92, 54, 22, 15, 17, 80, 47, 73]
ages.sort(reverse=True)
print(ages)
assert ages[0] <= ages[-1]
[92, 80, 73, 57, 54, 47, 26, 22, 17, 15]
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/563161254.py in <module>
2 ages.sort(reverse=True)
3 print(ages)
----> 4 assert ages[0] <= ages[-1]
AssertionError:
设定断言条件:数组内元素小于等于11,当大于11时,则循环终止,抛出AssertionError异常。
进阶提示: 在循环中使用assert断言,当不满足条件时,则循环终止,不继续执行。
templist = [i for i in range(0,20,2)]
print(templist)
for i in range(len(templist)):
assert templist[i] <=11
print(templist[i])
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
0
2
4
6
8
10
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_13696/2403374297.py in <module>
2 print(templist)
3 for i in range(len(templist)):
----> 4 assert templist[i] <=11
5 print(templist[i])
AssertionError:
4、输入模块pyinputplus
pyinputplus是加强版input(),带有各种验证功能。
inputStr()类似于内置的input,但是具有一般的PyInputPlus功能。 inputNum()确保用户输入数字并返回值。 inputChoice()确保用户输入系统提供的选项之一。 inputMenu()、inputDatetime()、inputYesNo()、inputBool()、input Email()、inputFilepath()、inputpassword()。\
关键字参数min、max、greaterThan、lessThan、blank、limit、timeout、default、allowRegexes、blockRegexes:
min关键字:输入不能小于min参数(输入可以等于他) max关键字:输入不能大于max参数(输入可以等于他) greateThan关键字:输入必须大于此参数(输入不能等于他) lessThan关键字:输入必须小于此参数(输入不能等于他) 默认情况下,除非将blank参数设置为True,否则不允许输入空格字符 给limit关键字提供一个整数,让PyInputPlus的函数在用户输入错误的情况下循环几次 timeout关键字指定用户在x秒内输入完成 default关键字参数在程序放弃或者用户无效输入时返回一个参数 allowRegexes、blockRegexes关键字可以使用正则表达式…
我们首先通过pip install安装pyinputplus包
pip install pyinputplus
确保用户输入数字
import pyinputplus as pyip
response = pyip.inputNum()
a
'a' is not a number.
1
确保用户输入数字,输入提示:“Enter a number:”
response = pyip.inputInt(prompt='Enter a number: ')
Enter a number: b
'b' is not an integer.
Enter a number: 12
当我们不知道某个语句用法的时候,直接输入help(),获得语法帮助
help(pyip.inputChoice)
确保用户输入系统提供的选项之一
response = pyip.inputChoice(['girl','boy'])
Please select one of: girl, boy
boys
'boys' is not a valid choice.
Please select one of: girl, boy
girl
输入数字的最小值是4
response = pyip.inputNum('Enter num: ', min=4)
Enter num: 2
Number must be at minimum 4.
Enter num: 5
输入数字的大于4
response = pyip.inputNum('Enter num: ', greaterThan=4)
Enter num: 4
Number must be greater than 4.
Enter num: 5
大于等于4,小于6
response = pyip.inputNum('>>>', min=4, lessThan=6)
>>>5
如果希望使输入成为可选的,以便用户无需输入任何内容,请使用blank=True。
response = pyip.inputNum(blank=True)
limit增加输入次数限制,如超出次数则报RetryLimitException错误。
try:
response = pyip.inputNum(limit=2)
except Exception as ex:
print(repr(ex))
aa
'aa' is not a number.
c
'c' is not a number.
RetryLimitException()
timeout为限制输入时间,默认计量单位为秒,如果超时则报TimeoutException错误。
try:
response = pyip.inputNum(timeout=3)
except Exception as ex:
print(repr(ex))
1
TimeoutException()
5、前期内容补充
快速填充list数组
spam = [1, 2, 3]
spam = spam + ['A', 'B', 'C']
print(spam)
print(spam * 3)
[1, 2, 3, 'A', 'B', 'C']
[1, 2, 3, 'A', 'B', 'C', 1, 2, 3, 'A', 'B', 'C', 1, 2, 3, 'A', 'B', 'C']
快速填充dict字典,加入enumerate枚举可以填充Key值
supplies = ['pens', 'staplers', 'flamethrowers', 'binders']
print(dict(enumerate(supplies,2)))
{2: 'pens', 3: 'staplers', 4: 'flamethrowers', 5: 'binders'}
shuffle random实现快速打乱顺序
import random
people = ['Alice', 'Bob', 'Carol', 'David']
random.shuffle(people)
print(people)
['Carol', 'Alice', 'Bob', 'David']
dict字典排序不分先后
eggs = {'name': 'Zophie', 'species': 'cat', 'age': '8'}
ham = {'species': 'cat', 'age': '8', 'name': 'Zophie'}
eggs == ham
True
list数组排序分先后
spam = ['cats', 'dogs', 'moose']
bacon = ['dogs', 'moose', 'cats']
spam == bacon
False
两种方法实现字符串内字符快速统计: ①循环用dict方式实现 setdefault()语法,实现如果key不存在于dict中,将会添加键并将值设为默认值1,如果字典中包含有给定键,则返回该键对应的值,否则返回为该键设置的值。
message = 'It was a bright cold day in April,中文文字whod the clocks were striking thirteen.'
count = {}
for c in message:
count.setdefault(c, 0)
count[c] += 1
print(count)
{'I': 1, 't': 6, ' ': 12, 'w': 3, 'a': 3, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 4, 'c': 3, 'o': 3, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, '中': 1, '文': 2, '字': 1, 'e': 5, 'k': 2, '.': 1}
②利用set(message)去重后,在用message.count()统计求出去重后的每个字符在字符串中出现的总次数。
message = 'It was a bright cold day in April,中文文字whod the clocks were striking thirteen.'
total = {word:message.count(word) for word in set(message)}
print(total)
{'k': 2, 's': 3, 'g': 2, 'w': 3, 'c': 3, '文': 2, 'y': 1, 'n': 3, '字': 1, 'a': 3, 'd': 3, 'A': 1, ' ': 12, 'l': 3, '中': 1, '.': 1, 'r': 5, ',': 1, 'i': 6, 'o': 3, 't': 6, 'e': 5, 'I': 1, 'p': 1, 'b': 1, 'h': 4}
1.islower 是否都是小写 2.isupper 是否都是大写 3.isalpha 是否都是字母 4.isalnum 是否都是数字
spam = 'Hello, world!'
print(spam.islower())
print(spam.isupper())
print('abc'.isalpha())
print('123a'.isalpha())
print('123'.isalnum())
False
False
True
False
True
字符串对齐rjust\ljust\center(num,character)
print('Hello'.rjust(20, '*'))
print('Hello'.ljust(20, '-'))
print('Hello'.center(20, '='))
***************Hello
Hello---------------
=======Hello========
ord()语法主要用来返回对应字符的ascii码 chr()语法主要用来表示ascii码对应的字符,可以用十进制,也可以用十六进制
print(ord('A'))
print(chr(65))
print(chr(0x61))
65
A
a
6、课后作业,答案在下一讲
1、计算银行带来的回报,假设你存银行一笔钱是10000,年利率是5%,则计算20年后,变成了多少钱?打印每一年的变化
您的代码:
2、(扩展)在第一题的基础上通过matplotlib绘制一张x(金额)/y(年)的曲线图(收益表)
您的代码:
3、安装并使用输入模块pyinputplus,完成age输入验证(数字0~110,最多输入2次),性别输入(男、女,限时10秒钟内),输出年龄,性别
您的代码:
4、制作一个菜单,其中包括小吃、饮料、主食等分类,每个分类下包含多种食物,左边是名字右边是价格,请尽量美观的把菜单打印出来。
menu_dict={ “1.主食”:{“1.面条”:6,“2.米饭”:2,“3.抄手”:8,“4.馒头”:1}, “2.饮料”:{“1.芬达”:3,“2.无糖可乐”:4,“3.面汤”:1,“4.酸梅汁”:2}, “3.小吃”:{“1.甩饼”:4,“2.糍粑”:7,“3.小油条”:8,“4.金银馒头”:6}, }
您的代码:
*(挑战)5、编程实践项目
判卷问题:设计一个自动判卷程序
我们帮助数学老师判卷子,本次数学题一共10题,每题10分。已经知道正确答案分别是"adbdcacbda",要求输入学生结果能找出错误并指出最终分数。
您的代码:
7、Python零基础速成班-第5讲-Python函数,Function和Lambda基础 课后作业及答案
1、编写一个名为make_shirt() 的函数,传入参数为size+logo(默认值是"ilovechina"),这个函数应打印一个句子,说明T恤的尺码和字样。使用位置形参或关键字形参分别调用该函数。
def make_shirt(size,logo="ilovechina")->"输出T恤":
print("T恤的尺寸是%s,字样是%s" %(size,logo))
make_shirt("XL")
make_shirt(logo="Python",size="XL")
T恤的尺寸是XL,字样是ilovechina
T恤的尺寸是XL,字样是Python
2、已知一个数列:1、1、2、3、5、8、13、……,其规律为从第3项开始,每一项都等于其前两项的和,这个数列就是斐波那契数列。请求出符合斐波那契数列规律的第(27)项的值。
def fib(n:"第几项")->"输出和":
if n == 1 or n== 2:
return 1
else:
return fib(n-2)+fib(n-1)
fib(27)
196418
3、通过lambda和map方法设计一个男女宝宝身高预测计算器,公式为
女
:
(
男
+
女
)
2
女:\frac{(男+女)}{2}
女:2(男+女)?
男
:
(
男
+
女
)
2
?
1.08
男:\frac{(男+女)}{2}*1.08
男:2(男+女)??1.08
并为以下组合计算宝宝预测身高(假设男宝宝1,女0):性别[1,0,1,0]父亲身高[175,180,172,178]母亲身高[160,165,159,162] 。
gender=[1,0,1,0]
father=[175,180,172,178]
mother=[160,165,159,162]
guess = list(map(lambda g,f,m:(f+m)/2 if g==0 else (f+m)/2*1.08,gender,father,mother))
guess
[180.9, 172.5, 178.74, 170.0]
4、通过lambda和reduce的方法设计一个程序寻找随机数组(20个0~100)中的最小值。
from functools import reduce
import random
list4 = random.sample(range(0,100),20)
print("list={}\nmin_element= {}".format(list4,reduce(lambda x,y:x if x<y else y,list4)))
list=[38, 81, 94, 82, 12, 85, 92, 98, 78, 71, 9, 59, 60, 20, 8, 89, 74, 42, 99, 50]
min_element= 8
|