zoukankan      html  css  js  c++  java
  • python基础知识--9迭代器生成器闭包与装饰器

    1.迭代器


    for i in range(1,10):
    print(i,end=' ')

    运行结果:

    1 2 3 4 5 6 7 8 9

    本章之前的代码,使用过for循环语句的,本质上都是迭代器的应用;
    迭代器,可以理解为一个容器,循环的时候,每次从容器中取出一个数据,直到数据被取完为止。

    如何自定义一个迭代器
    以类为例:
    需要在类中,实现两个方法 __iter__ 与 __next__

    其中:
    1. __iter__ 方法需要返回对象本身,它是for循环使用迭代器的要求;
    2. __next__ 方法用于返回容器中下一个元素,当容器中的数据取完时,需要引发 StopIteration异常。



    # 需求:
    # 1.自定义迭代器,通过传入最小值最大值,返回该范围所有数值的3次方
    # 2.将返回的值,存入num_list 列表中

    #%%

    class Number():
    def __init__(self,min,max):
    self.min = min
    self.max = max
    def __iter__(self):
    return self
    def __next__(self):
    # 返回这个范围内所有数值的3次方
    num = self.min

    if self.min <= self.max:
    self.min +=1
    return num **3
    else:
    raise StopIteration

    for i in Number(1,10):
    print(i,end =' ')
    运行结果:
    1 8 27 64 125 216 343 512 729 1000 

    num_list = []
    for i in Number(1,5):
    num_list.append(i)

    num_list
    运行结果:
    [1, 8, 27, 64, 125]
    2.生成器如果一个列表中,存有海量的数据,如果仅仅只是想访问其中某几个元素,那么这样的操作会特别耗内存;

    生成器特点:
    1.操作海量数据,节约大量内存空间。

    生成器创建:
    函数中如果包含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


    # yield 与 return 区别
    # return后,会跳出当前函数。yield 不会跳出当前函数。
    # yield保存当前函数的执行状态,在返回后,函数又回到之前保存的状态继续执行。

    #%%

    def test():
    return 1
    return 2

    def genetest():
    yield 1
    yield 2


    test = genetest()


    next(test)
    运行结果:1

    next(test)
    运行结果:2

    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):
    print(a+b)
    return inner

    def outer():
    a = 0
    def inner(b):
    nonlocal a
    a +=b
    return inner

    f = outer()

    f(30)

    f.__closure__[0].cell_contents

    运行结果:40

    # 闭包作用
    # 1.定制装饰器
    # 2.并行运算
    # ....
    4.装饰器
    def func():
    print('hello func')

    def func1():
    print('hello func1')

    # 需求:
    # 给上面函数,加上两句打印
    # print('开始执行')
    # print('结束执行')

    def func():
    print('开始执行')
    print('hello func')
    print('结束执行')


    装饰器


    装饰器是一种增加函数或类功能的简单方法,它可以快速地给不同的函数或类传入相同的功能。
    调用被装饰的函数,与之前的调用过程没有任何的区别

    # 基本格式

    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 执行结束

    @decorate
    def func1():
    print('hello func1')

    func1()
    运行结果:
    执行开始
    hello func1
    执行结束


  • 相关阅读:
    ROSBAG的使用以及TF_OLD_DATA问题
    cmake 编译安装库到指定目录
    QT 文件夹内文件查询与删除
    数组直接写入vector向量的方法与问题
    github上下载开源项目
    组件
    对象(二)
    对象(一)
    事件
    rem 、em
  • 原文地址:https://www.cnblogs.com/tester007/p/13865202.html
Copyright © 2011-2022 走看看