Python零基础速成班-第6讲-Python异常处理Exception,try&except,raise,assert,输入模块pyinputplus

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码对应的字符,可以用十进制,也可以用十六进制

#  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
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值