Python-Level1-day16:异常处理try-exceptraise语句,for迭代原理,深入手写创建迭代器;yield浅出使用生成器
作业 1. 三合一 2. 当天练习独立完成 3. 将员工管理系统分为4个模块employee_system.py 4. (选做)完成2048上下移动函数-- 自定义矩阵转置函数,实现行列颠倒-- 向上移动(矩阵转置,调用向左移动函数,矩阵转置)-- 向下移动(矩阵转置,调用向右移动函数,矩阵转置)
三
class EmployeeModel:def __init__(self, eid=0, did=0, name="", money=0):self.eid = eidself.did = didself.name = nameself.money = money
from model import EmployeeModel class EmployeeController:"""商品信息控制器"""__start_id = 1001 @classmethoddef __set_employee_id(cls, emp):emp.eid = cls.__start_idcls.__start_id += 1 def __init__(self):self.__all_employee = [] # type:List[EmployeeModel] @propertydef all_employee(self):return self.__all_employee def add_employee(self, emp: EmployeeModel):"""添加商品信息:param employee:需要添加的商品信息"""EmployeeController.__set_employee_id(emp)self.__all_employee.append(emp) def remove_employee(self, eid: int) -> bool:"""根据商品编号删除商品信息:param cid:商品编号:return:是否删除成功"""for i in range(len(self.__all_employee)):if self.__all_employee[i].eid == eid:del self.__all_employee[i]return Truereturn False def update_employee(self, commodity: EmployeeModel) -> bool:"""修改商品信息:param commodity:商品信息:return:是否删除成功"""for item in self.__all_employee:if item.eid == commodity.eid:item.__dict__ = commodity.__dict__return Truereturn False
from model import EmployeeModel class EmployeeView:"""商品信息视图""" def __init__(self, controller):self.__controller = controller # type:EmployeeController def main(self):while True:self.__display_menu()self.__select_menu() def __display_menu(self):print("1 添加员工")print("2 显示员工")print("3 删除员工")print("4 修改员工") def __select_menu(self):item = input("请输入您的选项:")if item == "1":self.__input_employee()elif item == "2":self.__display_employees()elif item == "3":self.__delete_employee()elif item == "4":self.__modify_employee() def __input_employee(self):employee = EmployeeModel()employee.name = input("请输入员工名称:")employee.did = int(input("请输入部门编号:"))employee.money = int(input("请输入员工工资:"))self.__controller.add_employee(employee) def __display_employees(self):for item in self.__controller.all_employee:print(item.__dict__) def __delete_employee(self):cid = int(input("请输入员工编号:"))if self.__controller.remove_employee(cid):print("删除成功")else:print("删除失败") def __modify_employee(self):employee = EmployeeModel()employee.eid = int(input("请输入员工编号:"))employee.name = input("请输入员工名称:")employee.did = int(input("请输入部门编号:"))employee.money = int(input("请输入员工工资:")) if self.__controller.update_employee(employee):print("修改成功")else:print("修改失败")
"""pyc文件让程序运行不用从头开始。节约时间与性能 """ from bll import EmployeeController #alt+enter导入 from usl import EmployeeView if __name__ == '__main__':view = EmployeeView(EmployeeController())view.main()
四
"""2048 游戏核心算法谈架构显示(界面)与控制(算法)分离 谈算法1. 高内聚:类内部的各个方法相可以互调用并且关系紧密(代码复用高)上下移动 -矩阵转置-> 左右移动向左移动 --> 合并数据 --> 零元素后移向右移动 -翻转-> 合并数据 --> 零元素后移2. 低耦合:类与类之间关系不大,修改一个类不影响用另外一个类类内部高内聚,类与类低耦合3. 降维思想:将二维列表的操作,改为对一维列表的操作. """ list_merge = [2, 0, 0, 2] # 做成全局的,省得下面好几个函数定义形式参数了 # 为什么函数不做返回值,因为所有函数直接操作的都是可变对象,所以返回值不写 def zero_to_end():"""零元素向后移动思想:从后向前判断,如果是0则删除,在末尾追加."""for i in range(len(list_merge) - 1, -1, -1):if list_merge[i] == 0:del list_merge[i]list_merge.append(0) # zero_to_end() # print(list_merge) def merge():"""合并数据核心思想:零元素后移,判断是否相邻相同。如果是则合并."""zero_to_end()for i in range(len(list_merge) - 1):if list_merge[i] == list_merge[i + 1]:list_merge[i] += list_merge[i + 1]del list_merge[i + 1]list_merge.append(0)# 加分 # merge() # print(list_merge) map = [[2, 0, 0, 2],[4, 2, 0, 2],[2, 4, 2, 4],[0, 4, 0, 4], ] def move_left():global list_mergefor line in map:list_merge = linemerge() # move_left() # print(map) def move_right():global list_mergefor line in map:# 从右向左获取数据形成新列表list_merge = line[::-1]# 处理数据merge()# 将处理后的数据再从右向左还给mapline[::-1] = list_merge # move_right() # print(map) def square_matrix_transposition():for c in range(1, len(map)): # 1 2 3for r in range(c, len(map)):map[r][c - 1], map[c - 1][r] = map[c - 1][r], map[r][c - 1] def move_up():"""向上移动思想: 转置 move_left 转置 """square_matrix_transposition()move_left()square_matrix_transposition() # 6. 向下移动 def move_down():"""向下移动思想: 转置 move_right 转置:return:"""square_matrix_transposition()move_right()square_matrix_transposition() # move_up() move_down() print(map)
异常处理 Error
异常
定义:运行时检测到的错误。
现象:当异常发生时,程序不会再向下执行,而转到函数的调用语句。
常见异常类型:
-- 名称异常(NameError):变量未定义。
-- 类型异常(TypeError):不同类型数据进行运算。
-- 索引异常(IndexError):超出索引范围。
-- 属性异常(AttributeError):对象没有对应名称的属性。
-- 键异常(KeyError):没有对应名称的键。
--值异常(ValueError):输入错误值
-- 异常基类 (父类)Exception。
处理
语法:
try:
可能触发异常的语句
except 错误类型 1 [as 变量 1]:
处理语句 1
except 错误类型 2 [as 变量 2]:
处理语句 2
except Exception [as 变量 3]:
不是以上错误类型的处理语句
else:
未发生异常的语句
finally:
无论是否发生异常的语句
作用:将程序由异常状态转为正常流程。
说明:
as 子句是用于绑定错误对象的变量,可以省略
except 子句可以有一个或多个,用来捕获某种类型的错误。
else 子句最多只能有一个。
finally 子句最多只能有一个,如果没有 except 子句,必须存在。
如果异常没有被捕获到,会向上层(调用处)继续传递,直到程序终止运行。
"""异常处理异常处理不适用以下语法错误,适用于解决逻辑错误(往往数据不在有效规定范围) """ """ list01 = [] print(list01[2]) print(abc) """ def div_apple(apple_count):person_count = int(input("people number"))result = apple_count / person_countprint(f"每个人{result}个") div_apple(10) # ValueError:控制台输入不合法数据 print("输入异常也继续执行后续逻辑") # 整个程序全部崩溃,需要提出一种错误处理机制
"""通过调试观察发现:程序执行过程 1-->2--->3 出错 -->2-->1 """ #3 def div_apple(apple_count):person_count = int(input("people number"))result = apple_count/person_countprint(f"每个人{result}个") #2 def main():div_apple(10) #1 main() print("输入异常也继续执行后续逻辑")
"""解决方案:异常处理作用让程序错误了,也可以往下执行 """ # 写法1:包治百病(掌握) def div_apple(apple_count):try:person_count = int(input("people number"))result = apple_count / person_countprint(f"每个人{result}个")except Exception: # 现在直接可以等价于excpet: Exception都不用写了print("分苹果失败") # 写法2:对症下药Exception换成ValueError与ZeroDivisionError等等 def div_apple(apple_count): # 名称相同取就近更新的函数try:person_count = int(input("people number"))result = apple_count / person_countprint(f"每个人{result}个")except ValueError:print("输入不是整数")except ZeroDivisionError:print("输入不能是零") # 写法3 # 无论是否发生错误都一定执行的结果,并且不执行后续逻辑 # 以上代码成功就不执行异常处理代码,然后执行后续逻辑 def div_apple(apple_count): # 名称相同取就近更新的函数try:person_count = int(input("people number"))result = apple_count / person_countprint(f"每个人{result}个")finally: # 分苹果成功失败都执行下面语句print("不知道分苹果还是失败,我都执行") # 写法4 # else作用:没有错误才执行的逻辑 def div_apple(apple_count): # 名称相同取就近更新的函数try:person_count = int(input("people number"))result = apple_count / person_countprint(f"每个人{result}个")except:print("分苹果失败")else:print("分苹果成功") def main():div_apple(10) main() print("后续逻辑")
"""练习:创建函数,在终端中录入int类型成绩。如果格式不正确,重新输入。效果: """ # 虽然异常处理解决了不报错问题,但可以通过结合循环方式实现输入出错也可以重写执行 def get_score():while True:try:score = int(input("please"))return scoreexcept:print("重写输入") score = get_score() print("成绩是 %d" % score)
对学生信息管理系统输入异常进行改造代码
from model import StudentModel from bll import StudentController class StudentView:"""学生视图:处理界面逻辑""" def __init__(self, controller=None):self.__controller = controller # type:StudentController def __display_menu(self):print("按1键录入学生信息")print("按2键显示学生信息")print("按3键删除学生信息")print("按4键修改学生信息") def __get_right(self, message):while True:try:num = int(input(message))return numexcept:print("输入有误,重新输入") def __select_menu(self):item = input("请输入您的选项:")if item == "1":# 先写方法调用,再alt+回车自动生成self.__input_student()elif item == "2":self.__display_students()elif item == "3":self.__delete_student()elif item == "4":self.__modify_student() def __input_student(self):stu = StudentModel()stu.name = input("请输入学生姓名:")stu.score = self.__get_right("请输入学生成绩:")stu.age = self.__get_right("请输入学生年龄:")self.__controller.add_student(stu)print("添加成功") def main(self):"""入口"""while True:self.__display_menu()self.__select_menu() def __display_students(self):for stu in self.__controller.students:print(stu) def __delete_student(self):sid = self.__get_right("请输入学生编号:")if self.__controller.remove_student(sid):print("删除成功")else:print("删除失败") def __modify_student(self):stu = StudentModel()stu.sid = self.__get_right("请输入需要修改的学生编号:")stu.name = input("请输入需要修改的学生姓名:")stu.age = self.__get_right("请输入学生年龄:")stu.score = self.__get_right("请输入学生成绩:")if self.__controller.update_student(stu):print("修改成功")else:print("修改失败")
from bll import StudentController from usl import StudentView #这个文件标蓝了,前提是其他同名文件不要标蓝,不然系统会找错文件 # 如果当前是主模块,才执行入口逻辑 if __name__ == '__main__':try:controller = StudentController()view =StudentView(controller)view.main()except:print("这叫全局异常处理,不应该是我们应用层开发人员做的") #异常处理是在哪一步错的,就哪一部处理,在这步处理不了,再返回上层次处理。 #因此异常处理精髓是就近处理原则
raise 语句
作用:抛出一个错误,让程序进入异常状态。与try expect搭配使用
目的:在程序调用层数较深时,向主调函数传递错误信息要层层 return 比较麻烦,
所以人为抛出异常,可以直接快速传递错误信息。
"""人为创造异常:目的是快速传递消息快速理解:这叫慢1-->2-->3-->2--->1这叫快1-->2-->3-->1 """ class Wife:def __init__(self, age=0):self.age = age # 2 @propertydef age(self):return self.__age @age.setterdef age(self, value):if 20 < value < 30: # 3self.__age = valueelse: # 人为创造异常,主动制造raise Exception("设置年龄有误") while True:try: # 接收异常jn = Wife(int(input("please"))) # 1print(jn.age)breakexcept Exception as error:print(error.args) # 将上面设定的字符串打印 # 或者except: # print("年龄范围输入过了")
迭代
每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
可迭代对象 iterable
定义:具有iter函数的对象,可以返回迭代器对象。
语法
-- 创建:
class 可迭代对象名称:
def iter(self):
return 迭代器
-- 使用:
for 变量名 in 可迭代对象:
语句
原理:
迭代器 = 可迭代对象.iter()
while True:
try:
print(迭代器.next()
except StopIteration:
""" 可迭代对象 迭代:iteration :重复下一个元素 迭代器:iterator:执行迭代过程的对象iterator 可迭代 iterable:可以创建迭代器的对象message 面试题目:for能够参与for循环条件是什么?答:具有iter函数能够创建迭代器对象 """ message = "abcdefg" # for item in message: # print(item) #for循环原理 #1.获取迭代器对象 iterator = message.__iter__() #2.获取下一个元素 while True:try:item = iterator.__next__()print(item)#3 如果停止迭代推出循环except StopIteration:break
""" 练习 1:创建列表,使用迭代思想,打印每个元素. 练习 2:创建字典,使用迭代思想,打印每个键值对. """ list01 = [1, 2, 3, 4, 5] iterator = list01.__iter__() while True:try:item = iterator.__next__()print(item)except:break dict01 = {1: 'a', 2: 'b', 3: 'c'} iterator = dict01.__iter__() while True:try:item = iterator.__next__()print(item, dict01[item])except:break
"""迭代器 """ # 声明:下列代码主要用于学习创建迭代器 class StudentIterator:"""学生迭代器"""def __init__(self, data):self.__data = dataself.__index = -1 def __next__(self):if self.__index == len(self.__data) - 1:raise StopIteration()self.__index += 1return self.__data[self.__index] class StudentController:"""学生可迭代对象"""def __init__(self):self.__students = [] def add_student(self, stu):self.__students.append(stu) def __iter__(self):return StudentIterator(self.__students) controller = StudentController() controller.add_student("郭世鑫") controller.add_student("刘兰涛") controller.add_student("穆东宇") # for item in controller: # print(item) # iterator = controller.__iter__() while True:try:item = iterator.__next__()print(item) #except StopIteration:break
"""图形状生迭代器""" class ComodityIterator:def __init__(self, data):self.__data = dataself.__index = -1 def __next__(self):if self.__index == len(self.__data) - 1:raise StopIteration()self.__index += 1return self.__data[self.__index] class GraphicController: def __init__(self):self.__graphics = [] def add_graphic(self, gra):self.__graphics.append(gra) def __iter__(self):return ComodityIterator(self.__graphics) controller = GraphicController() controller.add_graphic("圆形") controller.add_graphic("矩形") controller.add_graphic("三角形") for item in controller:print(item) iterator = controller.__iter__() while True:try:item = iterator.__next__()print(item) #except StopIteration:break
"""商品生迭代器""" class ComodityIterator:def __init__(self, data):self.__data = dataself.__index = -1 def __next__(self):if self.__index == len(self.__data) - 1:raise StopIteration()self.__index += 1return self.__data[self.__index] class CommodityController: def __init__(self):self.__comoditys = [] def add_commodity(self, com):self.__comoditys.append(com) def __iter__(self):return ComodityIterator(self.__comoditys) controller = CommodityController() controller.add_commodity("屠龙刀") controller.add_commodity("倚天剑") controller.add_commodity("芭比娃娃") for item in controller:print(item) iterator = controller.__iter__() while True:try:item = iterator.__next__()print(item) #except StopIteration:break
# 练习 3:创建自定义 range 类,实现下列效果. # class NumberIterator: # def __init__(self, data): # self.__data = data # self.__index = -1 # # def __next__(self): # if self.__index == len(self.__data) - 1: # raise StopIteration() # self.__index += 1 # return self.__data[self.__index] # # # # class MyRange: # def __init__(self,num): # self.data = [] # for i in range(num): # self.data.append(i) # # def __iter__(self): # return NumberIterator(self.data) # # # for number in MyRange(5): # print(number) # 0 1 2 3 4 class MyRangeIterator:def __init__(self, end):self.__number = -1self.__end = end def __next__(self):if self.__number == self.__end - 1:raise StopIteration()self.__number += 1return self.__number class MyRange:def __init__(self, stop):self.__stop = stop def __iter__(self):return MyRangeIterator(self.__stop) # 循环一次 计算一次 返回一次 不攒着 根本不费内存 for number in MyRange(2000000):print(number) # 0 1 2 3 4 mr = MyRange(5) iterator = mr.__iter__() while True:try:item = iterator.__next__()print(item) # 0 1 2except StopIteration:break
迭代器对象 iterator
定义:可以被 next()函数调用并返回下一个值的对象。
语法
class 迭代器类名:
def init(self, 聚合对象):
self.聚合对象= 聚合对象
def next(self):
if 没有元素:
raise StopIteration
return 聚合对象元素
说明:
-- 聚合对象通常是容器对象。
作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又
无需了解其内部结构。
生成器函数
定义:含有 yield 语句的函数,返回值为生成器对象。
语法
-- 创建:
def 函数名():
…
yield 数据
…
-- 调用:
for 变量名 in 函数名():
语句
说明:
-- 调用生成器函数将返回一个生成器对象,不执行函数体。
-- yield 翻译为”产生”或”生成”
执行过程:
(1) 调用生成器函数会自动创建迭代器对象。
(2) 调用迭代器对象的next()方法时才执行生成器函数。
(3) 每次执行到 yield 语句时返回数据,暂时离开。
(4) 待下次调用next()方法时继续从离开处继续执行。
原理:生成迭代器对象的大致规则如下
-- 将 yield 关键字以前的代码放在 next 方法中。
-- 将 yield 关键字后面的数据作为 next 方法的返回值。
"""yield ---生成器--浅出 """ class StudentController:"""学生可迭代对象""" def __init__(self):self.__students = [] def add_student(self, stu):self.__students.append(stu) def __iter__(self):# 生成代码的大致规则:# 1. 将yield关键字前面的代码作为__next__函数体# 2. 将yield关键字后面的数据作为__next__返回值index = 0yield self.__students[index] index += 1yield self.__students[index] index += 1yield self.__students[index] controller = StudentController() controller.add_student("郭世鑫") controller.add_student("刘兰涛") controller.add_student("穆东宇") # for item in controller: # print(item) # iterator = controller.__iter__()#调用iter函数,函数体不干,因为这个函数在next函数里面 while True:try:item = iterator.__next__()print(item) #except StopIteration:break
"""MyRange 2.0 精辟在yelid 直接取代了迭代器对象(里面有 iter 与 创造异常) """ class MyRange:def __init__(self, stop):self.__stop = stop def __iter__(self): number = 0yield number number += 1yield number number += 1yield number number += 1 # 循环一次 计算一次 返回一次 for number in MyRange(3):print(number) # 0 1 2 mr = MyRange(3) iterator = mr.__iter__() while True:try:item = iterator.__next__()print(item) # 0 1 2except StopIteration:break #写成while循环传入的参数就有效了
Python-Level1-day16:异常处理try-exceptraise语句,for迭代原理,深入手写创建迭代器;yield浅出使用生成器相关推荐
- 系统学习Python——异常处理:raise语句
如果要显式地触发异常,可以使用raise语句.它们的一般形式相当简单.一条raise语句的组成包括raise关键字,后面跟着可选的要引发的异常类或者异常类的一个实例: raise instance # ...
- python基础语法-异常处理
python中的异常处理 类似于java 开发中很常用 异常处理的好处 大大减少了由于异常程序崩溃的发生. 三个基本语句 try:在try语句后放入可能出现问题的代码,没有问题正常执行 except: ...
- 警惕Python编程中异常处理结构可能的坑
推荐一本用于修炼Python编程内功的好书<Python程序设计开发宝典>(本文封面图片),扫码了解详情(京东链接): ============================== 所谓异 ...
- python学习总结----异常处理
python学习总结----异常处理 相关概念- 错误:程序运行之前的语法错误,如:关键字.缩进不齐.括号不成对. - 异常:在程序运行过程中出现的问题,如:除数为0.对象属性不存在等.异常处理- 说 ...
- Python基础:异常处理
Python基础:异常处理 一,学习的内容 Python 异常处理 异常就是运行期检测到的错误.计算机语言针对可能出现的错误定义了异常类型,某种错误引发对应的异常时,异常处理程序将被启动,从而恢复程序 ...
- Python异常和异常处理
Python中的异常处理与Java中的做法思路类似,个别细节的地方需要注意下即可,理解起来没有太大问题 try-except块及finally 异常常用小技巧: (1)在类型转换的地方检查类型转换是否 ...
- Python进阶与拾遗8:Python中的异常处理
Python进阶与拾遗8:Python中的异常处理 异常相关概念 异常的定义 异常的角色 常用的异常处理方法 try/except/else/finally语句 raise语句 assert语句 wi ...
- Python 上下文管理器和 with 语句
1. 上下文管理器概念 什么是 Python 的上下文管理器(Context Managers)呢? 含有 __enter__ 和 __exit__ 方法的对象就是.上下文管理器存在的目的是管理 ...
- python输出print(x+y)_Python语句序列“x='car';y=2; print(x+y)”的输出结果是_学小易找答案...
[单选题]下列标识符中,合法的是( ). [填空题]若 a=10 ,那么 bin(a) 的值为 __________ . [单选题]如果在 Python 程序中没有导人相关的模块 ( 例如 impor ...
最新文章
- 自问自答:在VB中如何实现像C++一样printf的功能
- 菜鸟自学数据结构系列——(一)如何写出能够在VC下运行的单链表生成程序
- 757计算机电子元件,飞行员的好帮手 波音757的发动机指示与机组报警系统简介...
- SAP CRM和Cloud for Customer的Account merge
- Introduction-to-React-JS -- 2 Helloworld
- linux服务器管理公司用户,在Linux服务器Jenkins中管理用户和角色的方法
- Django通过中间件实现登录验证demo
- LeetCode--84.柱状图中最大的矩形(暴力法,单调栈)
- ROS笔记(1) ROS简介
- 路由表(FIB)的初始化
- 批量关停azure vm_如何在Azure中使用Visual Studio和VM数据库
- C++访问WebService(gSoap方式和com组件方式)
- 2019,数据库行业迎50年第二次巨变
- keil4注册机注册不了怎么办?我已经试过下面的注册机不行。求各大神指教一下?
- Flutter中的JSON解析
- 85条高级AutoCAD工程师绘图技巧(2)
- pagefile.sys占用空间过大问题
- Lorenzo Von Matterhorn
- Linux十大常用命令
- 怎么调用微信自带的收货地址和我的地址功能页面。