python1.day15
day14回顾
异常
错误
异常
作用:
用作信号通知
语句:
try-except语句
捕获异常,将程序由异常流程转为正常流程
try-finally语句
保证(正常/异常)流程时,有些语句一定能执行
raise 语句
触发异常通知,让程序进入异常流程
assert 语句
根据条件触发AssertionError类型的错误
异常类型:
ValueError, ImportError, ZeroDivisionError,
StopIteration, AssertionError, ....
BaseExcetion(基类)
迭代器
什么是迭代器?
函数:
iter(可迭代对象) 获取并返回迭代器
next(迭代器) 从迭代器中取数据,如果没有数据时会收到
StopIteration异常通知
for in 语句的实质是while语句+迭代器+try语句的组合
day15笔记:
生成器 Genertor (python2.5及之后)
什么是生成器
生成器是能够动态提供数据的可迭代对象
生成器是在程序运行时生成数据,与容器类不同,它通常不会在内
存在中保存大量的数据,而是现用现生成
生成器有两种:
生成器函数
生成器表达式
生成器函数的定义
含有yield 的语句的函数是生成器函数。此函数被调用将返回一
个生成器对象
yield翻译为(产生或生成)
yield语句
语法:
yield 表达式
说明:
yield 用于def函数中,目的是将此函数作为生成器函数使用
yield 用来生成数据,供迭代器的next(it) 函数使用
示例见:
yield.py

1 # yield.py 2 3 # 此示例示意生成器函数的定义和使用 4 def myyield(): 5 print("即将生成2") 6 yield 2 # 生成2 7 print("即将生成3") 8 yield 3 # 生成3 9 print("即将生成5") 10 yield 5 11 print("即将生成7") 12 yield 7 13 print("myyield函数运行结束!") 14 15 16 17 g = myyield() # 生成器函数调用将返回生成器对象,g绑写一个生成器 18 # print(g) 19 it = iter(g) # 让生成器提供迭代器 20 print(next(it)) # 2 21 22 print(next(it)) # 3 23 24 print(next(it)) # 5 25 26 print(next(it)) # 7 27 28 print(next(it)) # StopIteration异常 29 print("程序正常结束") 30 31 32 33

1 # yield.py 2 3 # 此示例示意生成器函数的定义和使用 4 def myyield(): 5 print("即将生成2") 6 yield 2 # 生成2 7 print("即将生成3") 8 yield 3 # 生成3 9 print("即将生成5") 10 yield 5 11 print("即将生成7") 12 yield 7 13 print("myyield函数运行结束!") 14 15 for x in myyield(): 16 print(x) 17 18 19 print("程序正常结束") 20 21 22 23 24 25 26
生成器函数说明:
1. 生成器函数的调用将返回一个生成器对象,生成器对象是一个可迭
代对象
2. 在生成器函数调用return会触发一个StopIteration异常(即
生成数据结束)
生成器函数示例见:
myinteger.py

1 # myinteger.py 2 3 # 此示例示意自己写一个生成器函数,可以生成从0开始的一系列 4 # 整数,到n结束(不包含n) 5 def myinteger(n): 6 i = 0 7 while i < n: 8 yield i 9 i += 1 10 11 12 for x in myinteger(3): 13 print(x) 14 15 16
练习:
1. 写一个生成器函数myeven(begin, end), 用来生成从begin开始
到end结束的所有偶数(不包含end)
如:
def myeven(begin, end):
... 此处自己实现
for x in myeven(1, 10):
print(x) # 打印 2, 4, 6, 8
L = [x**2 for x in myeven(4, 9)]
print(L) # [16, 36, 64]

1 # 练习: 2 # 1. 写一个生成器函数myeven(begin, end), 用来生成从begin开始 3 # 到end结束的所有偶数(不包含end) 4 # 如: 5 # def myeven(begin, end): 6 # ... 此处自己实现 7 8 # for x in myeven(1, 10): 9 # print(x) # 打印 2, 4, 6, 8 10 # L = [x**2 for x in myeven(4, 9)] 11 # print(L) # [16, 36, 64] 12 13 14 def myeven(begin, end): 15 i = begin 16 while i < end: 17 if i % 2 == 0: # 是偶数 18 yield i 19 i += 1 20 21 for x in myeven(1, 10): 22 print(x) # 打印 2, 4, 6, 8 23 24 L = [x**2 for x in myeven(4, 9)] 25 print(L) # [16, 36, 64] 26
生成器表达式:
语法:
(表达式 for 变量 in 可迭代对象 [if 真值表达式])
说明:
if 子句可以省略
作用:
用推导式形式创建一个新的生成器
示例:
gen = (x**2 for x in range(1, 5))
it = iter(gen) # 拿到迭代器
print(next(it)) # 1
print(next(it)) # 4
print(next(it)) # 9
print(next(it)) # 16
print(next(it)) # StopIteration
说明:
生成器通常是一次性的,当数据获取完毕后将不能再提供数据
练习:
已知有列表:
L = [2, 3, 5, 7]
1. 写一个生成器函数,让此函数能够动态提供数据,数据为原列
表的数字的平方加1
2. 写一个生成器表达式,让此表达式能够动态提供数据,数据为原
列表的数字的平方加1
3. 创建一个列表,此列表内的数据为原列表L的数字的平方加1

1 # 练习: 2 # 已知有列表: 3 # L = [2, 3, 5, 7] 4 # 1. 写一个生成器函数,让此函数能够动态提供数据,数据为原列 5 # 表的数字的平方加1 6 # 2. 写一个生成器表达式,让此表达式能够动态提供数据,数据为原 7 # 列表的数字的平方加1 8 # 3. 创建一个列表,此列表内的数据为原列表L的数字的平方加1 9 10 11 12 L = [2, 3, 5, 7] 13 # 1. 写一个生成器函数,让此函数能够动态提供数据,数据为原列 14 # 表的数字的平方加1 15 def fun1(lst): 16 for x in lst: 17 yield x ** 2 + 1 18 19 # for x in fun1(L): 20 # print(x) 21 22 # 2. 写一个生成器表达式,让此表达式能够动态提供数据,数据为原 23 # 列表的数字的平方加1 24 25 for x in (a ** 2 + 1 for a in L): 26 print(x) 27 28 # 3. 创建一个列表,此列表内的数据为原列表L的数字的平方加1 29 L = [a ** 2 + 1 for a in L] 30 print(L) 31 32
练习:
试写一个生成器函数 myfilter,要求此函数与系统内建的filter
函数功能完全一致
如:
def myfilter(fn, iterable):
....
for y in myfilter(lambda x: x%2==0, range(10)):
print(y)

1 # 练习: 2 # 试写一个生成器函数 myfilter,要求此函数与系统内建的filter 3 # 函数功能完全一致 4 # 如: 5 # def myfilter(fn, iterable): 6 # .... 7 8 # for y in myfilter(lambda x: x%2==0, range(10)): 9 # print(y) 10 11 12 13 14 def myfilter(fn, iterable): 15 for x in iterable: 16 if fn(x): 17 yield x 18 19 for y in myfilter(lambda x: x%2==0, range(10)): 20 print(y)
2. 看下列语句块的输出结果是什么?为什么?
第一个程序:
L = [2, 3, 5, 7]
A = [x*10 for x in L]
it = iter(A)
print(next(it)) # 20
L[1] = 33
print(next(it)) # 30
第二个程序:
L = [2, 3, 5, 7]
A = (x*10 for x in L)
it = iter(A)
print(next(it)) # 20
L[1] = 33
print(next(it)) # 330
迭代工具函数
zip 函数
enumerate 函数
zip函数
zip(itere1[,iter2, ....]) 返回一个zip生成器对象,此对象
用于生成一个元组,此元组的数据分别来自于参数中的
每个可迭代对象,生成元组的个数由最小的可迭代对象大
小决定
示例:
numbers = [10086, 10000, 10010, 95588]
names = ['中国移动', '中国电信', '中国联通']
for t in zip(numbers, names):
print("t=", t)
for n, na in zip(numbers, names):
print(na, '的客服电话是:', n)
d = dict(zip(numbers, names)) # 创建字典
for t in zip(numbers, names, range(1, 100000)):
print(t)
zip 函数的实现原理示例见:
myzip.py
enumerate 函数
格式:
enumerate(iterable, start=0)
作用:
生成一个枚举对象,此枚举对象生成的数据将原可迭代对象的数据与
索引值形成元组(index, value) 形式返回
示例:
L = [3, 5, 8, 10]
for i, v in enumerate(L):
print('索引为', i, '的元素值为', v)
练习:
试用自己的方法实现myenumerate, 功能与enumerate完全相同
def myenumerate(iterable, start=0):
... # 此处自己实现
L = [3, 5, 8, 10]
for i, v in myenumerate(L):
print('索引为', i, '的元素值为', v)

1 # 练习: 2 # 试用自己的方法实现myenumerate, 功能与enumerate完全相同 3 # def myenumerate(iterable, start=0): 4 # ... # 此处自己实现 5 6 # L = [3, 5, 8, 10] 7 # for i, v in myenumerate(L): 8 # print('索引为', i, '的元素值为', v) 9 10 11 # 方法1 用while语句实现 12 # def myenumerate(iterable, start=0): 13 # it = iter(iterable) # 拿到迭代器 14 # while True: 15 # try: 16 # v = next(it) # 拿到一个值 17 # yield (start, v) 18 # start += 1 19 # except StopIteration: 20 # return 21 22 # 方法2 用for语句实现 23 def myenumerate(iterable, start=0): 24 for v in iterable: 25 yield (start, v) 26 start += 1 27 28 L = [3, 5, 8, 10] 29 for i, v in myenumerate(L): 30 print('索引为', i, '的元素值为', v) 31 32 33 34 35 36 37
字节串和字节数组
字节串 bytes(也叫字节序列)
作用:
存储以字节为单位的数据
字节串是不可变的字节序列
字节:
字节是0~255之间的整数。用来表一个字节(8个位)的取值
字节是数据存储的最小单位
创建空字节串的字面值:
B = b'' # B绑定空字节串
B = b""
B = b''''''
B = b""""""
创建非空字节串的字面值:
B = b'ABCD'
B = b"ABCD"
B = b'\x41\x42\x43\x44'
字节串的构造函数 bytes
bytes() 生成一个空的字节串,等同于b''
bytes(整数可迭代对象) 用可迭代对象初始化一个字节串
bytes(整数n) 生成n个值为0的字节串
bytes(字符串,encoding='utf-8') 用字符串转换编码生成一个
字节串
示例:
B = bytes() # B=b''
B = bytes(range(65, 69)) # B = b'ABCD'
B = bytes(10) # B=b'\x00\x00....'
B = bytes("hello", 'utf-8') # B=b'hello'
bytes 的运算:
+ += * *=
< <= > >= == !=
in / not in
索引和切片
示例:
b = b'abc123ABC'
b'A' in b # True
65 in b # True
print(b[0]) # 97
函数:
len(x), max(x), min(x), sum(x), any(x), all(x)
bytes 与 str的区别:
bytes 存储字节(0~255)
str存储unicode字符 (0~0x10FFFF)
bytes与str转换
编码(encode)
str -----------> bytes
b = s.encode(encoding='utf-8')
解码(decode)
bytes -----------> str
s = b.decode(encoding='utf-8')
示例:
s = "ABC中文"
b = s.encode('utf-8') # b = b'ABC\xe4\xb8\xad\xe6\x96\x87'
s2 = b.decode('utf-8') # s2 = 'ABC中文'
字节数组 bytearray
可变的字节序列
字节数组的构造函数 bytearray
(同字节串)
bytearray() 生成一个空的字节数组,等同于bytearray(b'')
bytearray(整数可迭代对象) 用可迭代对象初始化一个字节数组
bytearray(整数n) 生成n个值为0的字节数组
bytearray(字符串,encoding='utf-8') 用字符串转换编码生成一个
字节数组
运算:
+ += * *=
< <= > >= == !=
in / not in
索引Index / 切片 slice
(注: 字节数组的索引和切片可以赋值操作,规则同列表的索引和切片
赋值规则相同)
bytearray 的方法:
参见文档:
python_base_docs_html/bytearray.html
文件 File
什么是文件
文件是用于数据存储的单位
文件通常用来长期存储数据
文件中的数据是以字节为单位进行顺序存储的
文件操作的流程
1. 打开文件
2. 读写文件
3. 关闭文件
文件的打开和关闭:
文件需要在使用时先打开文件才能读写
在不需要读写文件时,应及时关闭文件以释放系统资源
任何操作系统,一个应用程序同时打开文件的数量有最大数限制
文件的打开函数:
open(file, mode='rt') 用于打开一个文件,返回此文件对象
如果打开失败,则会触发OSError类型的错误
文件的关闭方法:
F.close() 关闭文件,释放系统资源
文本文件的读取数据方法:
F.read([n])
F.readline()
F.readlines()
(文档参见: python_base_docs_html/文件.html)

1 mode 模式字符的含义 2 字符 含义 3 'r' 以只读方式打开(默认) 4 'w' 以只写方式打开,删除原有文件内容(如果文件不存在,则创建该文件并以只写方式打开) 5 'x' 创建一个新文件, 并以写模式打开这个文件,如果文件存在则会产生"FileExistsError"错误 6 'a' 以只写文件打开一个文件,如果有原文件则追加到文件末尾 7 'b' 用二进制模式打开 8 't' 文本文件模式打开 (默认) 9 '+' 为更新内容打开一个磁盘文件 (可读可写) 10 缺省模式是 'rt' 11 'w+b' 可以实现二进制随机读写,当打开文件时,文件内容将被清零 12 'r+b' 以二进制读和更新模式打开文件,打开文件时不会清空文件内容 13 'r+' 以文本模式读和更新模式打开文件,打开文件时不会清空文件内容 14 python 文件常用方法: 15 方法 说明 16 F.close() 关闭文件(关闭后文件不能再读写会发生ValueError错误) 17 F.readline() 读取一行数据, 如果到达文件尾则返回空行 18 F.readlines(max_chars=-1) 返回每行字符串的列表,max_chars为最大字符(或字节)数 19 F.writelines(lines) 每行字符串的列表 20 F.flush() 把写入文件对象的缓存内容写入到磁盘 21 F.read(size = -1) 从一个文件流中最多读取size个字符 22 F.write(text) 写一个字符串到文件流中,返回写入的字符数 23 二进制文件操作方法 24 F.tell() 返回当前文件流的绝对位置 25 F.seek(offset, whence=0) 改变数据流的位置,返回新的绝对位置 26 F.readable() 判断这个文件是否可读,可读返回True,否则返回False 27 F.writable() 判断这个文件是否可写,可写返回True,否则返回False 28 F.seekable() 返回这个文件对象是否支持随机定位 29 F.truncate(pos = None) 剪掉 自pos位置之后的数据,返回新的文件长度(字节为单位)
示例见:
file_open.py

1 # file_open.py 2 3 # 此示例示意打开一个文件, 同时对文件的内容进行读取操作 4 5 # 1. 打开文件 6 # f = open("myzip.py") 7 f = open("myfile.txt") 8 print("文件打开成功") 9 10 # 2.读取文件 11 12 # 3. 关闭文件 13 f.close() 14 print("文件关闭成功") 15 16
练习:
1. 写一个生成器函数myxrange(start, stop, step) 来生成一
系列整数,
要求:
myxrange的功能与range功能完全相同
不允许调用range函数和列表
用自己写的myxrange结合生成器表达式求 1~10内的奇数的平方和
print(sum((x for x in myxrange(1, 10) if x%2)))
2. 自己写一个文件(si.txt)内容如下:
写入内容如下:
xiaozhang,20,100
ziaoli,18,98
ziaowang,19,80
为学生信息管理系统添加一个功能
| 9) 从文件中读取学生数据(si.txt) |
读取学生信息并加载到内存中

1 # file : main.py 2 3 from menu import show_menu 4 from student_info import * 5 6 def main(): 7 infos = [] # 此列表用于保存学生数据 8 while True: 9 show_menu() 10 s = input("请选择: ") 11 if s == '1': 12 infos += input_student() 13 elif s == '2': 14 output_student(infos) 15 elif s == '3': 16 delete_student(infos) 17 elif s == '4': 18 modify_student_score(infos) 19 elif s == '5': 20 output_by_score_desc(infos) 21 elif s == '6': 22 output_by_score_asc(infos) 23 elif s == '7': 24 output_by_age_desc(infos) 25 elif s == '8': 26 output_by_age_asc(infos) 27 elif s == '9': 28 infos = read_from_file() 29 elif s == '10': 30 save_to_file(infos) # 保存 31 elif s == 'q': 32 break 33 34 main() 35

1 # file : menu.py 2 3 4 def show_menu(): 5 '''显示菜单''' 6 print("+---------------------------------+") 7 print("| 1) 添加学生信息 |") 8 print("| 2) 显示学生信息 |") 9 print("| 3) 删除学生信息 |") 10 print("| 4) 修改学生成绩 |") 11 print("| 5) 按学生成绩高-低显示学生信息 |") 12 print("| 6) 按学生成绩低-高显示学生信息 |") 13 print("| 7) 按学生年龄高-低显示学生信息 |") 14 print("| 8) 按学生年龄低-高显示学生信息 |") 15 print("| 9) 从文件中读取学生数据(si.txt) |") 16 print("| 10) 保存信息到文件(si.txt) |") 17 print("| q) 退出 |") 18 print("+---------------------------------+") 19 20

1 # file: student.py 2 3 def input_student(): 4 L = [] # 创建一个列表,准备存放学生数据的字典 5 while True: 6 n = input("请输入姓名: ") 7 if not n: # 如果用户输入空字符串就结束输入 8 break 9 try: 10 a = int(input("请输入年龄: ")) 11 s = int(input("请输入成绩: ")) 12 except ValueError: 13 print("您的输入有错,请重新输入!!!") 14 continue 15 d = {} # 一定要每次都创建一个新的字典 16 d['name'] = n 17 d['age'] = a 18 d['score'] = s 19 L.append(d) # 把d加入列表中L 20 return L 21 22 def output_student(L): 23 print("+---------------+----------+----------+") 24 print("| 姓名 | 年龄 | 成绩 |") 25 print("+---------------+----------+----------+") 26 for d in L: 27 name = d['name'] 28 age = str(d['age']) # 转为字符串 29 score = str(d['score']) # 转为字符串 30 print("|%s|%s|%s|" % (name.center(15), 31 age.center(10), 32 score.center(10))) 33 print("+---------------+----------+----------+") 34 35 def delete_student(L): 36 name = input("请输入要删除学生的姓名: ") 37 i = 0 # i 代表列表的索引 38 while i < len(L): 39 d = L[i] # d绑定字典 40 if d['name'] == name: 41 del L[i] 42 print("删除", name, "成功!") 43 break 44 i += 1 45 else: 46 print("删除失败!") 47 48 def modify_student_score(L): 49 pass 50 51 52 def output_by_score_desc(L): 53 def get_score(d): 54 return d['score'] 55 L2 = sorted(L, key=get_score, reverse=True) 56 output_student(L2) 57 58 def output_by_score_asc(L): 59 L2 = sorted(L, key=lambda d:d['score']) 60 output_student(L2) 61 62 def output_by_age_desc(L): 63 L2 = sorted(L, key=lambda d:d['age'], reverse=True) 64 output_student(L2) 65 66 def output_by_age_asc(L): 67 L2 = sorted(L, key=lambda d:d['age']) 68 output_student(L2) 69 70 71 def read_from_file(): 72 L = [] # 创建一个准备存放字典的列表 73 try: 74 # 1. 打开文件 75 # f = open("./si.txt") 76 # f = open("si.txt") 77 f = open("/home/tarena/aid1812/pbase/day16/student_project/si.txt") 78 # 2. 读取信息 79 try: 80 while True: 81 line = f.readline() # line='xiaozhang,20,100\n' 82 if not line: # 到达文件尾 83 break 84 s = line.strip() # 去掉左右两端的空白字符'xiaozhang,20,100' 85 lst = s.split(',') # ['xiaozhang', '20', '100'] 86 n = lst[0] 87 a = int(lst[1]) 88 scr = int(lst[2]) 89 d = dict(name=n, age=a, score=scr) 90 L.append(d) 91 finally: 92 # 3. 关闭文件 93 f.close() 94 print("读取数据成功") 95 except OSError: 96 print("读取数据失败") 97 except ValueError: 98 print("数据类型错误!") 99 return L 100 101 def save_to_file(L): 102 try: 103 f = open("si.txt", 'w') 104 # 循环写入每个学生的信息 105 for d in L: 106 # 每次写入一个学生的信息 107 f.write(d['name']) # 姓名 108 f.write(',') 109 f.write(str(d['age'])) # 年龄 110 f.write(',') 111 f.write(str(d['score'])) # 成绩 112 f.write('\n') # 换行 113 f.close() 114 print("保存成功") 115 except OSError: 116 print("保存失败!") 117
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步