Python之路,第十五篇:Python入门与基础15

python3   异常

异常(基础)

什么是错误? 

错误是指由于逻辑或语法错误等,导致一个程序已无法正常执行的问题。

什么是异常?

异常是程序出错时标识的一种状态,当异常发生时,程序不会再向下执行,而转去调用此函数的地方,待处理相应的错误并恢复为正常状态;

try / except / else/ finally 语句

语法:

try:
  可能触发异常的语句
except  错误类型1 [as 变量1]:
  异常处理语句1
except    错误类型2 [as 变量2]:
  异常处理语句2
except    (错误类型3, 错误类型4, ...) [as 变量3]:
  异常处理语句3
...
except:
  异常处理语句other
else:
  未发生异常语句
finally:
  最终语句

语法说明:
  except    子句可以有一个或多个,但至少要有一个
  as     子句是用于绑定错误对象的变量,可以省略
  else   子句最多只能有一个,也可以省略
  finally   子句最多只能有一个,也可以省略不写

处理说明:
1.    except子句用来捕获和处理当某种类型的错误发生时,处理异常
2.    except 子句会根据错误的类型进行匹配,如匹配成功则调用异常处理语句进行处理,然后程序转为正常状态
3.    如果except子句没有匹配到任何类型的异常则转到except:子句
4.   如果没有任何except子句进行处理,则程序的异常状态会继续下去,并向上层传递
5.    如果没有异常,则执行else 子句中的语句
6.    最后执行finally子句中的语句

练习:
写一个程序,输入学生成绩(0~100之间的整数),如果输入出现异常,则设置此成绩变量的值为0

Python中的错误类型 :
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("程序结束!")
View Code

 

 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("程序结束!")
View Code

 

try / finally 语句
语法:
try:
  可能触发异常的语句
finally:
  最终语句
说明:
  1.    finally子句不可以省略
  2.    一定不存在except 子句

作用:
  通常用try / finally语句来做触发异常时必须要处理的事情,无论异常是否发生,finally子句都会被执行

注:
try / finally语句不会改变程序的(正常/异常)状态
示例见:try_finally.py

 1 def frag_egg():
 2     print("打个鸡蛋")
 3     print("打开天燃气...")
 4     print("找油")
 5     try:
 6         old = int(input("请输入油的位置:"))
 7         print("煎鸡蛋")
 8     finally:
 9         print("关闭天燃气")
10     # 此处出现异常 
11     # 3/0
12 
13 
14 # frag_egg()
15 
16 try:
17     frag_egg()
18 except:
19     print("处理完相应的事儿...")
20 
21 print("工作完成,可以就餐了....")
View Code

 


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 #程序错误
View Code
 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 #发生被零除的错误
View Code

 

 

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 p
20 
21 try:
22     score = get_score()
23     print("学生的成绩是:",score)
24 except AssertionError as err:
25     print(err)
View Code

 

 

迭代器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 #例子2
10 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 #1
20 #
21 #7
22 #iteration取值结束
23 #
View Code
 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 #1
12 #3
13 #5
14 #7
15 #9
16 #程序结束
View Code

 

 

生成器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 7
10     print("生成器函数调用结束")
11 
12 
13 it = iter(my_yield())
14 print(next(it)) #2
15 print(next(it)) #3
16 print(next(it)) #5
17 print(next(it)) #7
18 print(next(it)) #"生成器函数调用结束" ,触发StopIteration异常
View Code

说明:
生成器函数的调用将返回一个生成器对象,生成器对象是可迭代对象;
在生成器函数内调用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 #2
13 #3
View Code

 练习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 += 2
10     return L
11 
12 
13 for y in my_yield(10):
14     print(y, end=' ')
15 #1 3 5 7 9
16 def my_yield2(n):
17     x = 1
18     while x <= n:
19         yield x
20         x += 2
21 
22 
23 for y in my_yield2(10):
24     print(y, end=' ')
25 
26 #1 3 5 7 9
View Code

 

练习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 = s
30         stop = args[0]
31         step = 1
32     elif len(args) == 2:
33         start = s
34         stop,step = args
35     else:#只有一个参数传入时
36         start = 0
37         stop = s
38         step = 1
39     while start < stop:
40         yield start
41         start += 1
42 
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)])
View Code

 

生成器表达式
语法:
(表达式 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) #<generator object <genexpr> 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))#9
10 print(next(b))#StopIteration异常
View Code

迭代工具函数
作用;生成一个个性化的可迭代对象;
语法:
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 #中国联通 的客服电话是: 10010
10 
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 个是: 张飞
View Code

 

 

文件
什么是文件
        文件是存储数据的单位,通常用于长期存储数据;
文件分为普通文件和设备文件;
       普通文件是文件名和文件中的数据两部分组成;
文件的打开和关闭
       文件是需要在使用时先打开才能读写;
       在不使用文件时要关闭,应该及时关闭文件以释放系统资源;
       任何操作系统,打开的文件数有最大限制;


打开的文件函数:
      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("程序结束")
View Code

 

模式文件字符串的含义:
‘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 #aaa
12 #bbb
13 #ccc
14 #ddd
15 #
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 #aaa
22 #bbb
23 #ccc
24 #ddd
25 #eeee
View Code

 

二进制文件

bytes 类型和 bytearray类型
汉字编码
bytes 类型
以字节为单位存储数据,每个字节的值为0-255 [2**8 -1]

字符串可能是Unicode字符,字节是0-255之间的数
bytes 常量的表示方式:
b'' 空字节串
b'ABCD' 有四个字节的字节串
b'\x41\x42' 有两个字节的字节串
bytes运算(不能包含中文字节串)
+ 、 += 、 * 、 *=
< 、<= > >= == !=
in / not in
bytes 相关的函数:
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)
11 <class 'bytes'>
12 a=b'EF'
13 a+b
14 b'EFABCD'
15 a += b
16 a
17 b'EFABCD'
18 a
19 b'EFABCD'
20 b
21 b'ABCD'
22 b * 3
23 b'ABCDABCDABCD'
24 b *= 3
25 b
26 b'ABCDABCDABCD'
27 b'AB' > b'AB'
28 False
29 b'ac' > b'ab' 
30 True
31 b'ab' != b'AB'
32 True
33 b'\xff' < b'\xee'
34 False
35 b
36 b'ABCDABCDABCD'
37 b'A' in b
38 True
39 b'E' not in b
40 True
View Code

 

创建字节串(bytes)的函数
bytes()创建空的字节串
bytes (整数)
bytes(整型可迭代对象)
bytes(字符串,encoding='utf-8')

字节串可以看做序列,
字节串是不可变的,
>>>help(bytes) 查看帮助

一个汉字(字符)占三个字节串

bytes和str转换
str --> bytes

str.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 "<pyshell#3>", line 1, in <module>
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 >>> b
31 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 >>> 
View Code

 

posted on 2018-05-17 22:56  微子天明  阅读(246)  评论(0编辑  收藏  举报

导航