生成器和迭代器
迭代器
定义
迭代器是一个实现了选代协议的对象,它可以让我们遍历一个容器中的所有元素,而不需要知道容器的内部结构,迭代器可以被用于遍历列表、元组、字典、集合等容器类型。
工作原理
__iter__()
:方法返回迭代器对象本身,有__iter__()
方法的是一个可迭代对象。
__next__()
:返回容器中的下一个元素,直到容器中的所有元素都被遍历完毕后,再调用 next()方法就会抛出Stoplteration异常,表示迭代已结束。
有__next__()
方法的是迭代器
其他方法
# 返回iterator(迭代器)
print([1,2].__iter__())
print(iter([1,2,3]))
iter_l = [1,2,3,4,5]
iter_l = [1,2,3,4,5].__iter__()
# __length_hint__:获取的是迭代器元素的长度
print(iter_l.__length_hint__())
# __setstate__:根据索引指定索引位置
iter_l.__setstate__(3)
print(iter_l.__next__())
print(iter_l.__next__())
print(iter_l.__next__())
输出结果:
最后因为所有元素元素都被遍历,所以报错
迭代器的创建:
# 创建一个返回数字的迭代器,初始值为1,逐步递增1,并输出结果
class MyNum:
def __iter__(self): # 可迭代对象
self.num = 1
return self
def __next__(self):
n = self.num
self.num += 1
return n
mynum = MyNum()
# 获取迭代器对象
myiter = iter(mynum)
# myiter = mynum.__iter__()获取迭代器对象的迭代器
print(next(myiter))
print(next(myiter))
print(next(myiter))
生成器
定义
是Python中一种特殊的迭代器,它是一个能按需生成值的轻量级对象。
yield
yield
是一个关键字,用于定义生成器函数,生成器函数是一种特殊的函数,可以在迭代过程中逐步产生值,而不是一次性返回所有结果。
生成器是一个返回迭代器的函数,只能用于迭代操作
创建生成器
'''创建一个生成器'''
# 第一种方法:元组推导式
gen = (x*x for x in range(4))
List = [x*x for x in range(4)] # 以[]的为列表
print(gen)
print(List)
print()
# 第二种方法:生成器函数
def gen2():
for i in range(5):
yield i # yield表示暂停程序,可以使用next函数和sent函数唤醒程序
gen_2 = gen2()
print(gen_2)
print(next(gen_2))
print(next(gen_2))
print(gen_2.send(8))
用生成器模拟银行存款机
# 定义一个模拟银行取款机的函数
def bank_account():
# 最初金额
balance = 500
while True:
# 使用send函数传入amount的值
amount = (yield balance)
if amount is not None:
# 模拟存款,balance增加
if amount >= 0:
balance += amount
print(f"存款后,金额为{balance}")
# 模拟取款,balance减少
else:
# 取款金额大于本金,无法取出
if balance < -amount:
print(f"金额不足,无法取出")
# 取款金额小于本金,可以取出
elif balance >= amount:
balance += amount
print(f"取款后,金额为{balance}")
else:
print("没有存取款金额")
# 创建生成器实例
account = bank_account()
# 初始化生成器,执行到第一个yield语句
next(account)
# 使用send方法传入account的值
# 存入600元
account.send(600)
# 取出200元
account.send(-200)
# 再取出1000元
account.send(-1000)
生成器与迭代器的创建区别
1.生成器使用def
定义函数创建,只要有yield关键字就是生成器
2.迭代器使用class
来创建,需要同时包含__iter__()
和__next__()
两个方法才能使迭代器
闭包
定义
在一个函数的内部定义了另一个函数,外部的函数叫它外函数,内部的函数叫它内函数。
条件
1.在一个外部函数里定义一个内部函数
2.内部函数运用了外部函数的临时变量
3.外部函数的返回值是内部函数的引用
创建闭包
def outer(logo):
def inner(msg):
print(f"{logo}-{msg}-{logo}")
return inner
n1 = outer("吃饭")
n1("睡觉")
n1("打游戏")
# 输出结果:
# 吃饭-睡觉-吃饭
# 吃饭-打游戏-吃饭
用闭包实现银行取款功能
def outer(discount):
def inner(account):
nonlocal discount
if account is not None:
if account > 0:
discount+=account
print(discount)
else:
discount+=account
if discount >= 0:
print(discount)
else:
print("金额不足无法取出")
else:
print("没有计算金额")
return inner
n1 = outer(1500)
n1(500) # 输出:2000
n1(-600) # 输出:1400
n1(-1500) # 输出:金额不足无法取出
装饰器
实质上也是一个 闭包函数——函数嵌套。
作用
在不改变原函数的情况下,对已有函数进行额外的功能扩展。
条件
装饰器的形成条件(与包的区别):
1.不修改已有函数的源代码
2.不修改已有函数的调用方式
3.给已有函数增加额外的功能
实现装饰器
def decorator(func): # 将函数作为参数,装饰函数
def inner():
print("现在睡觉")
func()
print("起床了")
return inner
def sleep(): # 目标函数
import random
import time
print("睡眠中...")
time.sleep(random.randint(3,8))
fun = decorator(sleep)
fun()