python3 异常
异常(基础)
什么是错误?
错误是指由于逻辑或语法错误等,导致一个程序已无法正常执行的问题。
什么是异常?
异常是程序出错时标识的一种状态,当异常发生时,程序不会再向下执行,而转去调用此函数的地方,待处理相应的错误并恢复为正常状态;
try / except / else/ finally 语句
语法:
try:
可能触发异常的语句except 错误类型1 [as 变量1]: 异常处理语句1except 错误类型2 [as 变量2]: 异常处理语句2except (错误类型3, 错误类型4, ...) [as 变量3]: 异常处理语句3...except: 异常处理语句otherelse: 未发生异常语句finally: 最终语句语法说明:
except 子句可以有一个或多个,但至少要有一个 as 子句是用于绑定错误对象的变量,可以省略 else 子句最多只能有一个,也可以省略 finally 子句最多只能有一个,也可以省略不写处理说明:
1. except子句用来捕获和处理当某种类型的错误发生时,处理异常2. except 子句会根据错误的类型进行匹配,如匹配成功则调用异常处理语句进行处理,然后程序转为正常状态3. 如果except子句没有匹配到任何类型的异常则转到except:子句4. 如果没有任何except子句进行处理,则程序的异常状态会继续下去,并向上层传递5. 如果没有异常,则执行else 子句中的语句6. 最后执行finally子句中的语句练习:
写一个程序,输入学生成绩(0~100之间的整数),如果输入出现异常,则设置此成绩变量的值为0Python中的错误类型 :
ZeroDivisionError 除(或取模)零StopIteration 迭代器没有更多的值OverflowError 数值运算超出最大限制IOError 输入/输出操作失败ImportError 导入模块错误GeneratorExit 生成器发生异常来通知退出IndexError 序列中没有此索引FloatingPointError 浮点计算错误IndentationError 缩进错误TypeError 对类型无效的操作ValueError 传入无效的参数AssertonError 断言语句失败NameError 未声明/初始化对象AttributeError 对象没有这个属性KeyboardInterrupt 用户中断执行(通常是输入Ctrl+c)更多见: >>> help(__builtins__)
1 def div_apple(n): 2 print("现在有", n, "个苹果,请问分给几个人") 3 d = int(input("请输入人数:")) 4 print("每个人分", n / d, "个苹果") 5 6 7 try: 8 div_apple(10) 9 except ValueError as err:10 print("出现在值错误异常")11 print(err)12 except ZeroDivisionError:13 print("出现在被除数为零的错误,已转为正常状态")14 except:15 print("程序出现错误,已纠正!")16 else:17 print("这是else 子句,被执行了")18 finally:19 print("这是finnaly子句,我一定会被执行")20 21 print("程序结束!")
1 def div_apple(n): 2 print("现在有", n, "个苹果,请问分给几个人") 3 try: 4 d = int(input("请输入人数:")) 5 print("每个人分", n / d, "个苹果") 6 except ZeroDivisionError: 7 print("div_apple中已处理被零除错误") 8 9 10 try:11 div_apple(10)12 except:13 print("程序出现错误,已纠正!")14 else:15 print("程序没有异常")16 print("程序结束!")
try / finally 语句
语法: try: 可能触发异常的语句 finally: 最终语句说明: 1. finally子句不可以省略 2. 一定不存在except 子句作用:
通常用try / finally语句来做触发异常时必须要处理的事情,无论异常是否发生,finally子句都会被执行注:
try / finally语句不会改变程序的(正常/异常)状态示例见:try_finally.py1 def frag_egg(): 2 print("打个鸡蛋") 3 print("打开天燃气...") 4 print("找油") 5 try: 6 old = int(input("请输入油的位置:")) 7 print("煎鸡蛋") 8 finally: 9 print("关闭天燃气")10 # 此处出现异常 11 # 3/012 13 14 # frag_egg()15 16 try:17 frag_egg()18 except:19 print("处理完相应的事儿...")20 21 print("工作完成,可以就餐了....")
try嵌套 :示例:try: try: d = int(input("输入一个数:")) a = 3 / d finally: print("内部finally已执行")except: print("有异常发生")finally: print("外部finally已执行")
raise语句
作用:生成一个错误,让程序进入异常状态;语法:raise 异常状态或raise 异常对象1 def make_except(): 2 print("开始") 3 raise ValueError("值错误") 4 print("结束") #不执行 5 6 7 try: 8 make_except() 9 print("ABCD") #不执行10 except ValueError as e:11 print("发生错误,值为:",str(e))12 except:13 print("发现错误且已处理")14 print("程序错误")15 16 #开始17 #发生错误,值为: 值错误18 #程序错误
1 def f(x,y): 2 if y == 0: 3 raise ZeroDivisionError("y的值为0") 4 return x / y 5 6 try: 7 f(100,0) 8 except: 9 print("发生被零除的错误")10 11 #发生被零除的错误
assert 语句(断言语句)
语法:assert 真值表达式, 错误数据(通常字符串)作用:当真值表达式为False时, 用错误数据创建一个 AssertionError类型的错误,抛出后进入异常状态;等同于:if 真值表达式 == False: raise AssertionError(错误数据)1 def get_score(): 2 p = int(input("学生的成绩为:")) 3 if p > 100: 4 raise AssertionError("错误,成绩不能大于100!") 5 return p 6 7 try: 8 score = get_score() 9 print("学生的成绩是:",score)10 except AssertionError as err:11 print(err)12 13 ##########14 def get_score():15 p = int(input("学生的成绩为:"))16 assert p <= 100, "错误,成绩不能大于100!"17 #if p > 100:18 # raise AssertionError("错误,成绩不能大于100!")19 return p20 21 try:22 score = get_score()23 print("学生的成绩是:",score)24 except AssertionError as err:25 print(err)
迭代器Interator 和生成器 gennerator
什么是迭代器;迭代器是指能用next(it)函数取值的对象(实例)说明:用iter函数可返回一个可迭代对象的迭代器迭代器是访问可迭代对象的一种方式;迭代器只能往前,不会后退;函数iter(x)从一个对象x中返回迭代器,x必须能够提供一个迭代器的对象next(it), 从迭代器it中获取下一个记录,如果无法获取下一条记录,则触发StopIteration异常;#例子:1 L = [1,1,2,3,5] 2 it = iter(L) 3 print(next(it)) #1 4 print(next(it)) #1 5 print(next(it)) #2 6 print(next(it)) #3 7 print(next(it)) #5 8 print(next(it)) #StopIteration异常 9 #例子210 it = iter(range(1,10,3))11 print(next(it))12 print(next(it))13 print(next(it))14 try:15 print(next(it))16 except StopIteration:17 print("iteration取值结束")18 #执行结果19 #120 #21 #722 #iteration取值结束23 #
1 #打印1-10的奇数 2 it = iter(range(1,10,2)) 3 try: 4 while True: 5 print(next(it)) 6 except StopIteration: 7 print("程序结束") 8 #pass 9 10 ##11 #112 #313 #514 #715 #916 #程序结束
生成器generator
生成器是能够提供迭代器的对象(实例);生成器函数含有yield语句的函数是生成器函数;注:yield(生成或生产)yield语句语法:yield 表达式说明:yield用于def函数中,目的是将此函数作为生成器函数使用;yield用来生成数据,供迭代器next(it)函数使用;#例子:1 def my_yield(): 2 print("yield2 之前") 3 yield 2 4 print("yield3 之前") 5 yield 3 6 print("yield5 之前") 7 yield 5 8 print("yield7 之前") 9 yield 710 print("生成器函数调用结束")11 12 13 it = iter(my_yield())14 print(next(it)) #215 print(next(it)) #316 print(next(it)) #517 print(next(it)) #718 print(next(it)) #"生成器函数调用结束" ,触发StopIteration异常
说明:
生成器函数的调用将返回一个生成器对象,生成器对象是可迭代对象;在生成器函数内调用return,会产生一个StopIteration异常;1 def my_yield(): 2 yield 2 3 yield 3 4 return "我是生成器函数里的return语句" 5 #raise StopIteration("我是生成器函数里的return语句") 6 7 it = iter(my_yield()) 8 print(next(it)) 9 print(next(it))10 print(next(it))11 #StopIteration: 我是生成器函数里的return语句12 #213 #3
练习1
1 #写一个生成器函数 my_yield(x),传入一个终止值,可生成一个生成1,3,5...x奇数的生成器; 2 # 3 # 4 def my_yield(n): 5 L = [] 6 x = 1 7 while x <= n: 8 L.append(x) 9 x += 210 return L11 12 13 for y in my_yield(10):14 print(y, end=' ')15 #1 3 5 7 916 def my_yield2(n):17 x = 118 while x <= n:19 yield x20 x += 221 22 23 for y in my_yield2(10):24 print(y, end=' ')25 26 #1 3 5 7 9
练习2
1 #写一个生成器函数 myrange(stop)来生成一系列整数, 2 #要求:myrange与range功能完全一样,不允许调用range函数 3 #def myrange(stop): 4 # return range(stop) 5 # 6 #print([x for x in myrange(10)]) 7 ##print([x for x in myrange(5,10)]) 8 ##print([x for x in myrange(5,10,2)]) 9 #for x in range(10)10 # print(x)11 #def myrange(s, *args):12 # return range(s, *args)13 #14 #print([x for x in myrange(10)])15 #print([x for x in myrange(5,10)])16 #print([x for x in myrange(5,10,2)])17 #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]18 #[5, 6, 7, 8, 9]19 #[5, 7, 9]20 #def myrange(s, e=0, step=1):21 # return range(s,e,step)22 #23 ##print([x for x in myrange(10)])24 #print([x for x in myrange(5,10)])25 #print([x for x in myrange(5,10,2)])26 ##27 def myrange(s, *args):28 if len(args) == 1:29 start = s30 stop = args[0]31 step = 132 elif len(args) == 2:33 start = s34 stop,step = args35 else:#只有一个参数传入时36 start = 037 stop = s38 step = 139 while start < stop:40 yield start41 start += 142 43 print([x for x in myrange(10)])44 print([x for x in myrange(5, 10)])45 print([x for x in myrange(5, 10, 2)])
生成器表达式
语法:(表达式 for 变量 in 可迭代对象 [ if 真值表达式])注: if 子句可以省略作用:用推导式形式生成一个新的生成器(可迭代对象)1 a = [ x for x in range(10) if x % 2 ==1] 2 print(a) #[1, 3, 5, 7, 9] 3 b = ( x for x in range(10) if x % 2 ==1) 4 print(b) #at 0x00000000021E2A20> 5 print(next(b))#1 6 print(next(b))#3 7 print(next(b))#5 8 print(next(b))#7 9 print(next(b))#910 print(next(b))#StopIteration异常
迭代工具函数
作用;生成一个个性化的可迭代对象;语法:zip(iter1[, iter2[...]])返回一个zip对象,此对象用于生成一个元组,此元组的个数由最小的可迭代对象决定;enumerate(iterable [, start])生成带索引的迭代器,返回的迭代类型为索引-值对(index - value)对,默认索引从0开始,也可以用start指定;1 numbers = [ 10086, 10000, 10010, 95588] 2 names = ["中国移动","中国电信","中国联通"] 3 zip_m = zip(numbers, names) 4 for nu, name in zip_m: 5 print(name,"的客服电话是:", nu) 6 7 #中国移动 的客服电话是: 10086 8 #中国电信 的客服电话是: 10000 9 #中国联通 的客服电话是: 1001010 11 #zip 应用: 字典12 d = dict(zip(numbers, names))13 print(d)14 #{10000: '中国电信', 10010: '中国联通', 10086: '中国移动'}15 16 names = ["刘备","关羽", "张飞"]17 for nu, n in enumerate(names,1):18 print("第",nu,"个是:",n)19 20 #第 1 个是: 刘备21 #第 2 个是: 关羽22 #第 3 个是: 张飞
文件
什么是文件 文件是存储数据的单位,通常用于长期存储数据;文件分为普通文件和设备文件; 普通文件是文件名和文件中的数据两部分组成;文件的打开和关闭 文件是需要在使用时先打开才能读写; 在不使用文件时要关闭,应该及时关闭文件以释放系统资源; 任何操作系统,打开的文件数有最大限制; 打开的文件函数: open(file , mode='r')#用于打开一个文件,返回此文件的操作对象,如果打开文件失败则触发错误,抛出异常;
文件关闭方法:
F.close() #关闭文件 文本文件的常用方法:F.readline() 读取一行数据,如果到达文件尾则返回空行;(字符串包含行尾/n)F.readlines(n) 返回每行字符串的列表,n代表最大字符数(字节数)F.writelines(lines) 写入字符串中的列表f.write(x) 将数据(字符/字节)写入到文件中
F.flush() 把写入文件对象的缓存内容写入的磁盘;练习1
1 #第一种 2 f = open('test_data1.txt ', mode='r') 3 while True: 4 s = f.readline() 5 if len(s) == 0: break 6 s = s.rstrip() #去掉‘\n’ 7 l = s.split(' ') 8 print("姓名:",l[0],"电话:",l[1]) 9 f.close()10 #第二种11 f = open('test_data1.txt ', mode='r')12 L = f.readlines()13 #print(L)14 for s in L:15 s = s.rstrip()16 l = s.split(' ')17 print("姓名:",l[0],"电话:",l[1])18 f.close()19 #20 try:21 f = open('test_data1.txt ', mode='r')22 L = f.readlines()23 #print(L)24 for s in L:25 s = s.rstrip()26 l = s.split(' ')27 print("姓名:",l[0],"电话:",l[1])28 f.close()29 except IOError:30 print("打开文件失败")31 except:32 f.close()33 print("文件已关闭")34 35 print("程序结束")
模式文件字符串的含义:
‘r’ 指以只读的方式打开文件(默认)‘w’ 指以写的方式打开文件,删除原文件内容(如果文件不存在,则创建该文件并以只写的方式打开文件)‘x’ 创建一个新文件,并以写的模式打开,如果文件存在则会产生FileExistError错误;‘a’ 以追加写方式打开一个文件,如果有原文件则追加到原文件末尾;‘b’ 用二进制模式打开‘t’ 用文本文件模式打开(默认)‘+’ 为更新内容打开一个磁盘文件(可读可写)注:缺省模式是‘rt’ 帮助help(open)1 #f = open('newfile.txt','w') 2 #f.writelines(['aaa','bbb','ccc']) #创建文件写入内容aaabbbccc 3 # 4 #f.close() 5 # 6 #f = open('newfile.txt','w') 7 #f.writelines(['aaa\n','bbb\n','ccc\n']) 8 #f.writelines(['ddd\n']) 9 #f.close()10 #返回结果11 #aaa12 #bbb13 #ccc14 #ddd15 #16 f = open('newfile.txt','w')17 f.writelines(['aaa\n','bbb\n','ccc\n'])18 f.writelines(['ddd\n'])19 f.write('eeee\n')20 f.close()21 #aaa22 #bbb23 #ccc24 #ddd25 #eeee
二进制文件
bytes 类型和 bytearray类型
汉字编码bytes 类型以字节为单位存储数据,每个字节的值为0-255 [2**8 -1]字符串可能是Unicode字符,字节是0-255之间的数
bytes 常量的表示方式:b'' 空字节串b'ABCD' 有四个字节的字节串b'\x41\x42' 有两个字节的字节串bytes运算(不能包含中文字节串)+ 、 += 、 * 、 *=< 、<= > >= == !=in / not inbytes 相关的函数:len(x) 求字节的个数max(x)min(x)sum(x)any(x)all(x)1 b'' 2 b'' 3 b'' 4 b'' 5 b' ' 6 b' ' 7 b'ABCD' 8 b'ABCD' 9 b=b'ABCD'10 type(b)1112 a=b'EF'13 a+b14 b'EFABCD'15 a += b16 a17 b'EFABCD'18 a19 b'EFABCD'20 b21 b'ABCD'22 b * 323 b'ABCDABCDABCD'24 b *= 325 b26 b'ABCDABCDABCD'27 b'AB' > b'AB'28 False29 b'ac' > b'ab' 30 True31 b'ab' != b'AB'32 True33 b'\xff' < b'\xee'34 False35 b36 b'ABCDABCDABCD'37 b'A' in b38 True39 b'E' not in b40 True
创建字节串(bytes)的函数
bytes()创建空的字节串bytes (整数)bytes(整型可迭代对象)bytes(字符串,encoding='utf-8')字节串可以看做序列,
字节串是不可变的,>>>help(bytes) 查看帮助一个汉字(字符)占三个字节串
bytes和str转换
str --> bytesstr.encode(encoding='utf-8') 方法来转换
例:b = "英文abc".encode('utf-8')
bytes ---> str
B.decode(encoding='utf-8')
例: b'\xe8\x8b\xb1\xe6\x96\x87abc'.decode('utf-8')1 >>> bytes() 2 b'' 3 >>> bytes(10) #生成10个空字节串 4 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' 5 >>> bytes([0x41, 0x62, 99, 100]) 6 b'Abcd' 7 >>> bytes([0x41, 0x62, 99, 257]) 8 Traceback (most recent call last): 9 File "", line 1, in 10 bytes([0x41, 0x62, 99, 257])11 ValueError: bytes must be in range(0, 256)12 >>> bytes(range(65, 65+26))13 b'ABCDEFGHIJKLMNOPQRSTUVWXYZ'14 >>> bytes("ABCD", 'utf-8')15 b'ABCD'16 17 >>> bytes("ABCD中文",'utf-8')18 b'ABCD\xe4\xb8\xad\xe6\x96\x87'19 >>> bytes("ABCD中",'utf-8')20 b'ABCD\xe4\xb8\xad'21 >>> b1 = bytes("ABCD中",'utf-8')22 >>> for x in b1:23 print(x, end=' ')24 25 26 65 66 67 68 228 184 173 27 >>> "英文abc".encode('utf-8')28 b'\xe8\x8b\xb1\xe6\x96\x87abc'29 >>> b = "英文abc".encode('utf-8')30 >>> b31 b'\xe8\x8b\xb1\xe6\x96\x87abc'32 >>> b'\xe8\x8b\xb1\xe6\x96\x87abc'.decode('utf-8')33 '英文abc'34 >>> b.decode('utf-8')35 '英文abc'36 >>>