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编辑  收藏  举报

导航