Python-Level1-day16:异常处理try-except&raise语句,for迭代原理,深入手写创建迭代器;yield浅出使用生成器

作业
1. 三合一
2. 当天练习独立完成
3. 将员工管理系统分为4个模块
    employee_system.py
​
4. (选做)完成2048上下移动函数
    -- 自定义矩阵转置函数,实现行列颠倒
    -- 向上移动(矩阵转置,调用向左移动函数,矩阵转置)
    -- 向下移动(矩阵转置,调用向右移动函数,矩阵转置)

img

class EmployeeModel:
    def __init__(self, eid=0, did=0, name="", money=0):
        self.eid = eid
        self.did = did
        self.name = name
        self.money = money

from model import EmployeeModel
​
​
class EmployeeController:
    """
        商品信息控制器
    """
    __start_id = 1001
​
    @classmethod
    def __set_employee_id(cls, emp):
        emp.eid = cls.__start_id
        cls.__start_id += 1
​
    def __init__(self):
        self.__all_employee = []  # type:List[EmployeeModel]
​
    @property
    def 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 True
        return 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 True
        return 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_merge
    for line in map:
        list_merge = line
        merge()
​
# move_left()
# print(map)
​
​
def move_right():
    global list_merge
    for line in map:
        # 从右向左获取数据形成新列表
        list_merge = line[::-1]
        # 处理数据
        merge()
        # 将处理后的数据再从右向左还给map
        line[::-1] = list_merge
​
​
# move_right()
# print(map)
​
​
def square_matrix_transposition():
    for c in range(1, len(map)):  # 1 2 3
        for 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

异常

  1. 定义:运行时检测到的错误。

  1. 现象:当异常发生时,程序不会再向下执行,而转到函数的调用语句。

  1. 常见异常类型:

-- 名称异常(NameError):变量未定义。

-- 类型异常(TypeError):不同类型数据进行运算。

-- 索引异常(IndexError):超出索引范围。

-- 属性异常(AttributeError):对象没有对应名称的属性。

-- 键异常(KeyError):没有对应名称的键。

--值异常(ValueError):输入错误值

-- 异常基类 (父类)Exception。

处理

  1. 语法:

try:

可能触发异常的语句

except 错误类型 1 [as 变量 1]:

处理语句 1

except 错误类型 2 [as 变量 2]:

处理语句 2

except Exception [as 变量 3]:

不是以上错误类型的处理语句

else:

未发生异常的语句

finally:

无论是否发生异常的语句

  1. 作用:将程序由异常状态转为正常流程。

  1. 说明:

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_count
    print(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_count
    print(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_count
        print(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_count
        print(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_count
        print(f"每个人{result}个")
    finally:  # 分苹果成功失败都执行下面语句
        print("不知道分苹果还是失败,我都执行")
​
​
# 写法4
# else作用:没有错误才执行的逻辑
def div_apple(apple_count):  # 名称相同取就近更新的函数
    try:
        person_count = int(input("people number"))
        result = apple_count / person_count
        print(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 score
        except:
            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 num
            except:
                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 语句

  1. 作用:抛出一个错误,让程序进入异常状态。与try expect搭配使用

  1. 目的:在程序调用层数较深时,向主调函数传递错误信息要层层 return 比较麻烦,

所以人为抛出异常,可以直接快速传递错误信息。

"""
    人为创造异常:
        目的是快速传递消息
        快速理解:这叫慢1-->2-->3-->2--->1
                   这叫快1-->2-->3-->1
"""
​
​
class Wife:
    def __init__(self, age=0):
        self.age = age  # 2
​
    @property
    def age(self):
        return self.__age
​
    @age.setter
    def age(self, value):
        if 20 < value < 30:  # 3
            self.__age = value
        else:  # 人为创造异常,主动制造
            raise Exception("设置年龄有误")
​
​
while True:
    try:  # 接收异常
        jn = Wife(int(input("please")))  # 1
        print(jn.age)
        break
    except Exception as error:
        print(error.args)  # 将上面设定的字符串打印
# 或者except:
# print("年龄范围输入过了")

迭代

每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。

可迭代对象 iterable

  1. 定义:具有iter函数的对象,可以返回迭代器对象。

  1. 语法

-- 创建:

class 可迭代对象名称:

def iter(self):

return 迭代器

-- 使用:

for 变量名 in 可迭代对象:

语句

  1. 原理:

迭代器 = 可迭代对象.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 = 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 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 = 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 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 = 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 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 = -1
        self.__end = end
​
    def __next__(self):
        if self.__number == self.__end - 1:
            raise StopIteration()
        self.__number += 1
        return 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   2
    except StopIteration:
        break

迭代器对象 iterator

  1. 定义:可以被 next()函数调用并返回下一个值的对象。

  1. 语法

class 迭代器类名:

def init(self, 聚合对象):

self.聚合对象= 聚合对象

def next(self):

if 没有元素:

raise StopIteration

return 聚合对象元素

  1. 说明:

-- 聚合对象通常是容器对象。

  1. 作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又

无需了解其内部结构。

生成器函数

  1. 定义:含有 yield 语句的函数,返回值为生成器对象。

  1. 语法

-- 创建:

def 函数名():

yield 数据

-- 调用:

for 变量名 in 函数名():

语句

  1. 说明:

-- 调用生成器函数将返回一个生成器对象,不执行函数体。

-- yield 翻译为”产生”或”生成”

  1. 执行过程:

(1) 调用生成器函数会自动创建迭代器对象。

(2) 调用迭代器对象的next()方法时才执行生成器函数。

(3) 每次执行到 yield 语句时返回数据,暂时离开。

(4) 待下次调用next()方法时继续从离开处继续执行。

  1. 原理:生成迭代器对象的大致规则如下

-- 将 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 = 0
        yield self.__students[index]
​
        index += 1
        yield self.__students[index]
​
        index += 1
        yield 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 = 0
        yield number
​
        number += 1
        yield number
​
        number += 1
        yield 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   2
    except StopIteration:
        break
#写成while循环传入的参数就有效了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dpq666dpq666

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值