Python-9-Python迭代器、生成器与装饰器
9-1 迭代器
在本章之前的代码,for循环本质上是迭代器的应用。迭代器,可以理解为一个容器,循环的时候,每次从容器中取出一个数据,直到数据取完为止。
for i in range(1, 10): print(i, end=' ') #1 2 3 4 5 6 7 8 9
如何自定义一个迭代器
1. 以类为例,需要在类中定义两个方法:__iter__ 与 __next__,其中 __iter__ 方法需要返回对象本身,它是for循环使用迭代器的要求。__next__ 方法用于返回容器中下一个元素,当容器中数据取完时,需要引发 StopIteration 异常。
需求1:自定义迭代器,通过传入最小值最大值,返回该范围所有值的3次方。
class Number(): def __init__(self, min, max): #构造函数整个过程中只被调用一次 self.max = max self.min = min def __iter__(self): return self def __next__(self): num = self.min if self.min <= self.max: self.min += 1 #循环终止条件 return num **3 else: raise StopIteration for i in Number(1,5): print(i) ----------------------- 1 8 27 64 125
需求2:将返回的值,存入 num_list 列表中。
num_list = [] for i in Number(1,5): num_list.append(i) num_list ----------------------- [1, 8, 27, 64, 125]
9-2 生成器
使用场景:
如果在一个列表中,存有海量的数据,如果仅仅只是想访问其中某几个数据,那么这样的操作会特别耗内存。
生成器特点:
操作海量数据,节省大量内存空间。
生成器创建:
函数中若包含了 yield 关键字,那么这个函数就不再是一个普通函数,而是一个生成器(generator)对象。在Python中,使用了 yield 的函数被称为生成器(generator).
运行特点:
(1) 和普通函数不同的是,生成器是一个返回迭代器的函数,只能用于迭代操作,更简单点理解生成器就是一个迭代器。
(2) 在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有运行信息,返回 yield 的值,并在下一次执行 next() 方法时从当前位置继续执行。
#创建一个生成器,传入最大值最小值,执行 next() 方法。 def mygene(min, max): while min < max: yield min min += 1 my_gene = mygene(1, 5) next(my_gene) #1 next(my_gene) #2 next(my_gene) #3 next(my_gene) #4 next(my_gene) #5 next(my_gene) #StopIteration 报错
yield 与 return 的区别:return后会跳出当前函数,而yield不会跳出当前函数。yield会保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。
再一个例子:
def genetest(): yield 1 yield 2 test = genetest() next(test) #1 next(test) #2
9-3 简单聊一下闭包
闭包特点:
1. 函数内部再定义函数。
2. 内部函数引用了外部变量,但非全局变量。
3. 需要把内部函数返回。
闭函数例子:
def outer(): a = 0 def inner(b): print(a+b) return inner f = outer() f.__closure__[0].cell_contents #0 查看是不是闭函数,若返回a的值就说明是闭函数
内部函数如何修改外部函数的变量的值:
def outer(): a = 0 def inner(b): nonlocal a #声明a是一个外部函数的变量 a += b return inner f = outer() f(10) f.__closure__[0].cell_contents #10
闭包作用:1.定义装饰器 2.并行运算 ...
9-4 装饰器
装饰器是一种增加函数或类功能的简单方法,它可以快速地给不同的函数或类传入相同的功能。调用被装饰的函数,与之前的调用过程没有任何区别。
基本格式:
def decorate(func): #定义装饰器函数,参数为func,代表被装饰的函数 def wrapper(*args, **kwargs): #新定义一个包装函数,用于返回 func(*args, **kwargs) #调用被装饰的函数 return wrapper #返回包装函数
例子:
def decorate(func): #这个名字可以自己定义 def wrapper(*args, **kwargs): #这个名字也可以自定义 print("执行开始") func(*args, **kwargs) print("执行结束") return wrapper @decorate #加这个表示调用 def func(): print('hello func') func() #函数调用上没有任何区别 ---------------------- 执行开始 hello func 执行结束
posted on 2023-08-01 15:35 Hello-World3 阅读(28) 评论(0) 编辑 收藏 举报