简述python三神器——装饰器、迭代器、生成器

装饰器

在不修改函数的情况下,给函数添加新的功能。

闭包: 局部函数的内部函数里,对局部函数的变量进行引用,那么内部函数认为是闭包(closure)

什么是装饰器

装饰器(decorator) 的本质就是一个函数, 是增强函数或类的功能的一个函数。 装饰器是一个实参高阶函数也是返回值高阶函数。

简单装饰器

def cp(fn):
    def do_action(name, age, clock):
        if clock < 21:
            fn(name, age, clock)
        else:
            print('太晚了,不能玩了!')

    return do_action


@cp
def play_game(name, game, clock):
    print(f'{name}再玩会吧!{game}')


play_game('乌曼巴', 'balL', 20)
"""
乌曼巴再玩会吧!balL
"""
play_game('得分手', '王者荣耀', 23)
"""
太晚了,不能玩了!
"""

注意:@符号是装饰器的语法糖

常见的内置装饰器有三种,@property@staticmethod@classmethod

语法糖

语法糖(Syntactic sugar): 添加的某种语法,这种语法对语言的功能并没有影响,但是更方便程序员使用。语法糖提供了更易读的编码方式,可以提高开发效率。

迭代器

可迭代对象

可迭代对象: 重写了__iter__方法就是可迭代对象

  • 对象实现了__iter__方法
  • __iter__方法返回了一个迭代器对象

迭代器对象(迭代器-iterator)

迭代器对象: 实现了迭代器协议的对象。

  • 对象实现了__next__方法
  • __next__方法返回了某个数据(我们需要的是返回这个对象的特定的数据,并且按照一定的顺序进行依次返回)
  • __next__方法需要在值取完的时候,抛出StopIteration的错误信息。
  • 生成器亦是迭代器
# 只要重写了__iter__方法就是可迭代对象
# 实现了__next__方法。

class Demo(object):
    def __init__(self, x):
        self.x = x
        self.count = 0

    def __iter__(self):
        return self

    def __next__(self):
        self.count += 1
        if self.count <= self.x:
            return self.count - 1
        else:
            raise StopIteration


d = Demo(10)
for i in d:
    print(i)
"""
0
1
2
3
4
5
6
7
8
9
"""
# 调用对象方法
# print(d.__iter__().__next__())
"""
上面的for循环已经该迭代器对象把数据遍历完了
raise StopIteration StopIteration
"""
# 内置函数调用
i=iter(d)
print(next(i))
"""
raise StopIteration StopIteration
"""

生成器—generator

生成器就是可迭代对象,自动实现了迭代器协议,也可以这样说 在函数中有yield关键字的 就称为 生成器

yield关键字作用:

  • 保存当前运行状态(断点),然后暂停执行,即将生成器(函数)挂起
  • 将yield关键字后面表达式的值作为返回值返回,此时可以理解为起到了return的作用

next()函数也能让生成器从断点处继续执行,即唤醒生成器(函数)

斐波那契数列生成器


def fibonacci(n):
    current = 0
    num1 = num2 = 1
    num = 1
    while current < n:
        num = num1
        num1, num2 = num2, num1 + num2
        current += 1
        # return
        yield num


f1 = fibonacci(12)
print(f1)
for i in f1:
    print('fibonacc:', i)
"""
<generator object fibonacci at 0x00000233D485C848>
fibonacc: 1
fibonacc: 1
fibonacc: 2
fibonacc: 3
fibonacc: 5
fibonacc: 8
fibonacc: 13
fibonacc: 21
fibonacc: 34
fibonacc: 55
fibonacc: 89
fibonacc: 144
"""

send唤醒

使用send()函数可以在唤醒的同时向断点处传入一个附加数据,但是不能将非none值发送到刚刚启动的生成器。(即send()函数值为非None值,则不能第一个传入生成器中)

执行到yield时,gen函数作用暂时保存,返回i的值; temp接收下次c.send(“python”),send发送过来的值,c.next()等价c.send(None)。

错误实例

def gen():
    i = 0
    while i < 5:
        temp = yield i
        print(temp)
        i += 1


g = gen()
print(g)

print(g.send('hello'))  # TypeError: can't send non-None value to a just-started generator

正确实列

def gen():
    i = 0
    while i < 5:
        temp = yield i
        print(temp)
        i += 1


g = gen()
print(g)

print(g.send(None))
"""
<generator object gen at 0x0000029BE6153F48>
0
"""
def gen():
    i = 0
    while i < 5:
        temp = yield i
        print(temp)
        i += 1


g = gen()
print(g)
print(next(g))
print(g.send('乌曼巴'))
"""
<generator object gen at 0x0000027DB3B93F48>
0
乌曼巴
1
"""
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值