三大神器迭代器, 生成器, 装饰器

三大神器:迭代器, 生成器, 装饰器

迭代器

  • 什么是迭代器(iter)
"""
容器; 程序中无法直接创建一个迭代器, 只能将别的序列转换成迭代器.
可变(只能取), 有序(但不支持下标)
特点: 打印迭代器无法查看所有元素, 也无法获取元素的个数; 获取元素的时候每次只能获取最前面的元素, 而且元素取一个就少一个.

语法:
变量 = iter(序列)
"""
  • 查 - 获取元素

迭代器不管以什么样的方式获取到了某个元素, 那么这个元素一定会从迭代器中消失

取完了再取就报错

"""
1) 查单个: next(迭代器) - 获取迭代器中最前面的那个元素
2) 遍历 - for-in
"""

生成器

关键字yield

  • 什么是生成器
"""
容器; 其他容器是直接保存多个数据, 生成器保存产生多个数据的算法.
生成器获取数据的方式和特点和迭代器一样.
"""
  • 创建生成器
"""
调用一个带有yield关键字的函数就可以得到一个生成器对象
"""
  • 控制生成器产生数据的个数和值
"""
一个生成器产生的数据的个数和值,由创建生成器调用的那个函数的函数体在执行的时候会遇到几次yield, 以及每次yield后面的值来决定
个数: 由遇到的yield的次数决定
值: 由yield后面的数据决定
"""
  • 生成器创建数据的原理

打印带尖括号的本质是序列的对象, 可以按迭代器, 生成器去使用

"""
每次获取生成器的数据的时候, 就会去执行创建这个生成器的函数题, 但是每次执行都只会执行到yield就停下来
"""
  • 总结

生成器可以理解为一种特殊的程序执行规则, 而next与yield为告知程序执行生成器规则的标记

执行逻辑如下:

"""
主程序执行
遭遇next(变量) -> 进入变量保存的对象从头开始执行 -> 在函数中遭遇yield, 返回值并记录节点 -> 回到主程序执行next(变量)的下一步 -> 再次遭遇next(变量)(ps.和之前变量是同一个) -> 进入上次yield退出的节点,从yield下一条语句开始执行, ... 
"""

每一个迭代器或生成器对象都是一次性用品

装饰器

  • 什么是装饰器 - 给已经定义好的函数添加功能的工具
"""
装饰器就是一个函数, 这个函数既是实参高阶函数, 又是返回值高阶函数
"""
  • 给函数添加功能
  1. 直接修改原函数
  2. 新建函数, 新函数中调用原函数
  3. 使用装饰器

无参装饰器

  • 无参装饰器语法
"""
语法:
def 装饰器名(原函数):
    def 添加完功能的新函数(*args, **kwargs):
        调用原函数
        添加新功能
    return 添加完功能的新函数
    

语法细化:
def 装饰器名(f):
    def new_f(*args, **kwargs):
        result = f(*args, **kwargs)
        新增功能
        return result
    return new_f


装饰器名 - 根据新增的功能来命名
"""
  • 无参装饰器使用
"""
@无参装饰器名
定义函数
"""

有参装饰器

"""
语法细化:
def 装饰器名(参数列表):
    def 无参装饰器(f)
        def new_f(*args, **kwargs):
            result = f(*args, **kwargs)
            新增功能
            return result
        return new_f
    return 无参装饰器
    
使用:
@有参装饰器名()
定义函数
"""
  • 装饰器总结
  1. 装饰器的创建规则

    • 无参 - 两层函数嵌套 + 特定返回值(外层返回新函数, 内层返回被装饰函数返回值相关值)

    • 有参 - 三层函数嵌套 - 装饰器传参函数包裹无参装饰器, 传参函数返回值为无参装饰器

  2. 装饰器的调用规则

    装饰器两种调用方法实际是两个不同的标记, 旨在告诉计算机程序接下来部分按什么逻辑顺序执行

    • 无参 - @装饰器名
    • 有参 - @装饰器名(装饰器使用的形参列表)

    ps.语法中装饰器名为定义时最外层函数名

  3. 装饰器的调用运行逻辑

    • 无参
    """
    @装饰器名 -> def 被装饰函数(形参列表): -> 
    def new_fn(*args, **kwargs): -> 被装饰函数(实参) -> 执行new_fn并返回结果
    """
    
    """
    特殊规则的函数调用(将紧跟在后面定义的函数名作为实参传入装饰器函数运行) ->
    进入装饰前函数,运行内容为定义了一个新函数,然后返回定义的新函数(@装饰器名 + 定义被装饰函数这个代码段的结果是得到了一个新函数, 当原函数在装饰器外的环境中被调用时, 新函数替代原函数进行响应. 因此, 即使新函数中不调用原函数, 新函数返回值与原函数毫无关联, 不返回原函数返回值, 也不会报错, 只是失去了身为装饰器的意义) -> 装饰器外部调用原函数, 执行装饰器内的新函数(调用时传的参数也一并传给新函数的形参), 并返回新函数的返回值
    """
    
    def add_tag(str1='p', str2='a'):
        def temp(fn):
            def new_fn(*args, **kwargs):
                return 0
            return new_fn
        return temp
    
    
    @add_tag()
    def func1(x=0):
        if x:
            return 100
        return 'abc'
    
    
    print(func1(1))
    
    • 有参
    """
    @装饰器名(传给装饰器用的形参列表) -> def 装饰器名(装饰器用的形参列表): (ps.传参) -> 
    def 任意函数名(被装饰函数名): -> 返回上一步定义的函数的函数名
    """
    
    """
    特殊调用规则的标记 -> 执行装饰器最外层函数(包括两部分内容: 定义一个函数(有且只有一个形参的函数) + 返回值(返回值为定义的这个函数的函数名))
    因此, 这里实际变化为@装饰器名() ==> @装饰器最外层函数返回的函数名
    下一步就按无参装饰器执行规则进行
    """
    

生成器与装饰器的两要点:

  1. 标记
  2. 执行规则

标记在于提示计算机接下来的执行规则是什么(相当于程序员和计算机之间定的暗号, 而计算机根据不同的标记去做不同的事情)

一个由语言开发者定义封装的计算机执行规则, 标记为规则激活的密码

生成器的标记为: 一个语法规则(next(生成器对象)), 一个关键字(yield)

装饰器的标记为: 一个语法规则(@装饰器名 + 定义的函数)

迭代器或许可以看作看不到yield关键字的生成器(因为没有必要看到)

迭代器内的代码猜测:

def iter(序列形参):
    for x in 序列形参:
        yield x

调用时

变量1 = iter(序列实参)	# 序列实参传入函数, 返回一个生成器对象
变量2 = next(变量1)
"""
for x in 序列: -> yield返回序列中从最前面取出来的一个元素
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值