Python学习第十六天

raise 语句
1. 作用:抛出一个错误,让程序进入异常状态。
2. 目的:在程序调用层数较深时,向主调函数传递错误信息要层层return 比较麻烦,所以人为抛出异常,可以直接传递错误信息。

"""
    raise
"""


class Wife:
    def __init__(self, age=0):
        self.age = age  # 2

    @property
    def age(self):
        return self.__age

    @age.setter
    def age(self, value):  # 3
        if 22 <= value <= 30:
            self.__age = value
        else:
            # 主动抛出异常(快速传递错误消息)
            raise Exception("年龄超过范围",1,2,3)

try:
    w01 = Wife(300)  # 1
    print(w01.age)
except Exception as e: # 通过e变量操作抛出的异常对象
    print(e.args)
    print("出错啦")

迭代
每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。例如:循环获取容器中的元素。
可迭代对象iterable
1. 定义:具有–iter–函数的对象,可以返回迭代器对象。
2. 语法
– 创建:
class 可迭代对象名称:
def --iter–(self):
return 迭代器
– 使用:
for 变量名 in 可迭代对象:
语句
3. 原理:
迭代器 = 可迭代对象.–iter–()
while True:
try:
print(迭代器.–next–())
except StopIteration:
break
迭代器对象iterator
1. 定义:可以被next()函数调用并返回下一个值的对象。
2. 语法
class 迭代器类名:
def --init–(self, 聚合对象):
self.聚合对象= 聚合对象
def --next–(self):
if 没有元素:
raise StopIteration
return 聚合对象元素
3. 说明:
– 聚合对象通常是容器对象。
4. 作用:使用者只需通过一种方式,便可简洁明了的获取聚合对象中各个元素,而又无需了解其内部结构。

"""
    迭代 iter:每一次对过程的重复称为一次“迭代”,
             而每一次迭代得到的结果会作为下一次迭代的初始值。
        可迭代iterable:能够完成迭代过程的对象.
        迭代器iterator:实施迭代过程的对象
"""
message = "我是齐天大圣孙悟空"
# for item in message:
#     print(item)

# for 循环原理
# 1. 获取迭代器对象
iterator = message.__iter__()
while True:
    try:
        # 2. 获取下一个元素
        item = iterator.__next__()
        print(item)
        # 3. 如果没有元素,则停止循环.
    except StopIteration:
        break

# 面试题:可以参与for循环的条件是?
# 能够获取迭代器对象(可迭代对象)
# 具有__iter__函数

"""
    迭代器
    让自定义对象参与for循环
    迭代自定义对象
"""
class SkillIterator:
    def __init__(self, data):
        self.data = data
        self.index = -1

    def __next__(self):
        self.index += 1
        if self.index < len(self.data):
            return self.data[self.index]
        else:
            raise StopIteration()


class SkillManager:
    def __init__(self):
        self.__skills = []

    def add_skill(self, skill):
        self.__skills.append(skill)

    def __iter__(self):
        return SkillIterator(self.__skills)


manager = SkillManager()
manager.add_skill("降龙十八掌")
manager.add_skill("六脉神剑")
manager.add_skill("乾坤大挪移")

# 迭代自定义对象
# for skill in manager:
#     print(skill)

iterator = manager.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)  # 降龙十八掌
    except StopIteration:
        break

yield 生成迭代器代码的大致规则:
1. 将yield之前的代码定义到__next__方法中
2. 将yield之后的数据作为__next__方法返回值

"""
    迭代器 --> yield
"""
class SkillManager:
    def __init__(self):
        self.__skills = []

    def add_skill(self, skill):
        self.__skills.append(skill)

    # def __iter__(self):
    #     print("准备")
    #     yield self.__skills[0]
    #
    #     print("准备")
    #     yield self.__skills[1]
    #
    #     print("准备")
    #     yield self.__skills[2]
    def __iter__(self):
        for skill in self.__skills:
            print("准备")
            yield skill

        # yield 生成迭代器代码的大致规则:
        # 1. 将yield之前的代码定义到__next__方法中
        # 2. 将yield之后的数据作为__next__方法返回值

manager = SkillManager()
manager.add_skill("降龙十八掌")
manager.add_skill("六脉神剑")
manager.add_skill("乾坤大挪移")

# 迭代自定义对象
for skill in manager:
    print(skill)

# iterator = manager.__iter__()
# while True:
#     try:
#         item = iterator.__next__()
#         print(item)  # 降龙十八掌
#     except StopIteration:
#         break

# 现象:调用__iter__方法,但是不执行
#     调用__next__方法,执行__iter__方法
#     执行到yield返回,当再次调用__next__方法继续执行__iter__方法

生成器函数
1. 定义:含有yield语句的函数,返回值为生成器对象。
2. 语法
– 创建:
def 函数名():

yield 数据

– 调用:
for 变量名 in 函数名():
语句
3. 说明:
– 调用生成器函数将返回一个生成器对象,不执行函数体。
– yield翻译为”产生”或”生成”
4. 执行过程:
(1) 调用生成器函数会自动创建迭代器对象。
(2) 调用迭代器对象的__next__()方法时才执行生成器函数。
(3) 每次执行到yield语句时返回数据,暂时离开。
(4) 待下次调用__next__()方法时继续从离开处继续执行。
5. 原理:生成迭代器对象的大致规则如下
– 将yield关键字以前的代码放在next方法中。
– 将yield关键字后面的数据作为next方法的返回值。

"""
    yield --> 生成器
    MyRange3.0
    类 --> 函数
"""
"""
class Generator:# 生成器 = 可迭代对象 + 迭代器
    def __iter__(self): # 可迭代对象
        return self
    
    def __next__(self): # 迭代器
        ....
"""
def my_range(end):
    start = 0
    while start < end:
        yield start
        start += 1

for item in my_range(5):
    print(item)

# 延迟操作/惰性操作
# 循环一次 计算一次 返回一次
range = my_range(5)
iterator = range.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except StopIteration:
        break

练习一

"""
练习1:使用迭代思想,打印元组中所有元素。
练习2:不使用for循环,打印字典中所有记录(键和值)
"""
tuple01 = (43, 4, 5, 67, 87, 89)
iterator = tuple01.__iter__()
while True:
    try:
        item = iterator.__next__()
        print(item)
    except StopIteration:
        break

dict01 = {"a": "A", "b": "B"}
iterator = dict01.__iter__()
while True:
    try:
        key = iterator.__next__()
        value = dict01[key]
        print(key, value)
    except StopIteration:
        break

练习二

"""
    迭代员工管理器
"""


class EmployeeIterator:
    def __init__(self, data):
        self.data = data
        self.index = -1

    def __next__(self):
        self.index += 1
        if self.index < len(self.data):
            return self.data[self.index]
        else:
            raise StopIteration()


class EmployeeManager:
    def __init__(self):
        self.all_employee = []

    def add_employee(self, emp):
        self.all_employee.append(emp)

    def __iter__(self):
        return EmployeeIterator(self.all_employee)


manager = EmployeeManager()
manager.add_employee("老王")
manager.add_employee("老李")
manager.add_employee("老孙")

for item in manager:
    print(item)

练习三

"""
    自定MyRange类
    实现range(5)效果
"""


class MyRangeIterator:# 迭代器
    def __init__(self,stop):
        self.number = -1
        self.stop = stop

    def __next__(self):
        self.number += 1
        if self.number  < self.stop:
            return self.number
        else:
            raise StopIteration()

class MyRange:
    def __init__(self, end):
        self.end = end

    def __iter__(self):# 可迭代对象
        return MyRangeIterator(self.end)

# for item in MyRange(5):  # 0~4
#     print(item)

# 可以生成撑爆内存的数字
# 循环一次  计算一次  返回一次
for item in MyRange(9999999999999999999999999999999):
    print(item)

for item in range(9999999999999999999999999999999):
    print(item)

练习四

"""
    使用yield代替迭代器EmployeeIterator
    迭代员工管理器
"""


class EmployeeManager:
    def __init__(self):
        self.all_employee = []

    def add_employee(self, emp):
        self.all_employee.append(emp)

    def __iter__(self):
        for item in self.all_employee:
            yield item

manager = EmployeeManager()
manager.add_employee("老王")
manager.add_employee("老李")
manager.add_employee("老孙")

for item in manager:
    print(item)

练习五

"""
    MyRange1.0
    迭代器实现MyRange类
"""


class MyRangeIterator:# 迭代器
    def __init__(self,stop):
        self.number = -1
        self.stop = stop

    def __next__(self):
        self.number += 1
        if self.number  < self.stop:
            return self.number
        else:
            raise StopIteration()

class MyRange:
    def __init__(self, end):
        self.end = end

    def __iter__(self):# 可迭代对象
        return MyRangeIterator(self.end)

# for item in MyRange(5):  # 0~4
#     print(item)

# 可以生成撑爆内存的数字
# 循环一次  计算一次  返回一次
for item in MyRange(9999999999999999999999999999999):
    print(item)

for item in range(9999999999999999999999999999999):
    print(item)

练习六

"""
    MyRange2.0
    使用 yield 代替迭代器
"""
class MyRange:
    def __init__(self, end):
        self.end = end

    # 使用yield 返回0~4
    def __iter__(self):
        start = 0
        while start <  self.end:
            yield start
            start += 1

for item in MyRange(5):
    print(item)

练习七

"""
    返回列表中所有数字的个位
    方式1:传统思想
        定义函数,创建列表,循环计算每个元素的个位,存入列表
    方式2:生成器思想
        定义函数,循环计算每个元素的个位,通过yield返回
    体会:惰性操作/延迟操作/推算数据
"""

def find_number_unit(list_target):
    list_result = []
    for number in list_target:
        unit = number % 10
        list_result.append(unit)
    return list_result

# 测试
list01 = [54,55,36,67,28,69,90]
result = find_number_unit(list01)
for item in result:
    print(item)



def find_number_unit(list_target):
    for number in list_target:
        unit = number % 10
        yield unit

# 测试
list01 = [54,55,36,67,28,69,90]
# 调用不执行,延迟/惰性
result = find_number_unit(list01)
for item in result:
    print(item)

练习八

"""
    函数返回结果:
        return 数据  -- 单个
        yield 数据   -- 多个
"""
class EmployeeModel:
    def __init__(self, eid=0, did=0, name="", money=0.0):
        self.eid = eid
        self.did = did
        self.name = name
        self.money = money

list_employee = [
    EmployeeModel(1001, 9003, "林", 13000),
    EmployeeModel(1002, 9003, "王", 16000),
    EmployeeModel(1003, 9003, "刘", 11000),
    EmployeeModel(1004, 9003, "冯", 17000),
    EmployeeModel(1005, 9003, "曹", 15000),
    EmployeeModel(1006, 9003, "魏", 12000),
]

# 1. 定义函数,在list_employee中查找薪资大于等于15000的所有员工
def find_employees_gt_15k():
    for emp in list_employee:
        if emp.money >= 15000:
            yield emp
for item in find_employees_gt_15k():
    print(item.__dict__)

# 2. 定义函数,在list_employee中查找员工编号为1005的员工
def find_employee_at_eid():
    for emp in list_employee:
        if emp.eid == 1005:
            return emp
employee = find_employee_at_eid()
print(employee.__dict__)

# 3. 定义函数,在list_employee中查找所有员工的姓名
def select_names_by_employee():
    for emp in list_employee:
        yield emp.name

for name in select_names_by_employee():
    print(name)

# 4. 定义函数,在list_employee中查找薪资最高的员工
def get_max_employee_by_money():
    max_emp = list_employee[0]
    for i in range(1,len(list_employee)):
        if max_emp.money  < list_employee[i].money:
            max_emp = list_employee[i]
    return max_emp

emp = get_max_employee_by_money()
print(emp.__dict__)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值