迭代器,生成器,闭包,装饰器简介

1.迭代器(iterator)
1.1迭代器定义:
了解迭代器定义之前需先了解可迭代对象(iterable object)。
可迭代对象:可以用for循环调用,并不断返回下一个值的对象
迭代器就是一种可迭代对象,其定义为,可以被next()方法调用的并不断返回下一个值的可迭代对象,另外迭代器还需实现两个固定的方法 iter_和_next
2.生成器(generator)
定义:Python中使用了yield的函数被称为生成器。与普通函数不同的是生成器返回的是一个迭代器。或者可以理解为,生成器就是一个迭代器。在调用生成器的过程中,每次遇到yield函数,函数都会暂停,并保存当前所有运行信息,返回yield的值,并在下一次执行next()函数时从当前位置继续运行。
如果不明白可以看如下的代码解释:

 def foo():
        print("starting...")
        while True:
            res = yield 4
            print("res:",res)
    g = foo()
    print(next(g))
    print("*"*20)
    print(next(g))

上面的代码运行结果如下:

starting…
4
********************
res: None
4

(对于不明白yield的作用的我们可以先将yield看成return,并从中体会yield与return的区别)
上面代码的运行顺序可以用如下解释:
1.程序开始执行以后,因为foo函数中有yield关键字,所以foo函数并不会真的执行,而是先得到一个生成器g(相当于一个对象)

2.直到调用next方法,foo函数正式开始执行,先执行foo函数中的print方法,然后进入while循环

3.程序遇到yield关键字,然后把yield想想成return,return了一个4之后,程序停止,并没有执行赋值给res操作,此时next(g)语句执行完成,所以输出的前两行(第一个是while上面的print的结果,第二个是return出的结果)是执行print(next(g))的结果,

4.程序执行print("*"20),输出20个

5.又开始执行下面的print(next(g)),这个时候和上面那个差不多,不过不同的是,这个时候是从刚才那个next程序停止的地方开始执行的,也就是要执行res的赋值操作,这时候要注意,这个时候赋值操作的右边是没有值的(因为刚才那个是return出去了,并没有给赋值操作的左边传参数),所以这个时候res赋值是None,所以接着下面的输出就是res:None,

6.程序会继续在while里执行,又一次碰到yield,这个时候同样return 出4,然后程序停止,print函数输出的4就是这次return出的4.

同过如上解释我们就可以明白一个简单的生产器的功能,及yield的作用。
另外,生产期还有如下特性:(1)生成器可以用send方法实现和生成器内部进行交互,(2).可以用close方法关闭生成器。(3)可以用throw方法抛出生成器内部的异常。

3.闭包
闭包的简单定义为:定义在函数内部的函数。
根据其定义可能有些抽象,可以借助如下代码理解
一个简单的闭包代码如下:

def mul(a,b):
    def add(c):
        jg=a*b+c
        return jg
    return add

其调用运行代码如下(注意其调用方式)

result=mul(2,3)(10)
print(result)

其运行结果为

16

以上便是闭包的定义及简单的实例。

4.装饰器
其定义可以这样理解:不会对原来的函数造成改变,还要添加新的功能,并且调用函数时接口没有发生改变的程序。
下面我们用代码理解其功能的实现。
一个函数index如下:

import time


def index():
    time.sleep(2)

我们要对其进行装饰,增加一个功能,可以记录函数的运行时间
我们可以用如下代码

start_time=time.time()
index()
end_time=time.time()
rtime=end_time-start_time
print(rtime)

如上可以实现我们想要的功能,但是测试的函数过多,代码就会显的繁琐,所以我们可以做如下简化:

def calculate_time(f):
    start_time = time.time()
    f()
    end_time = time.time()
    rtime = end_time - start_time
    print(rtime)

简化过后,遇到另一个问题就是,功能实现了,但是实现功能时的接口改变了,所以我们可以利用闭包实现接口的统一,修改后代码如下:

def calculate_time(f):
    def inner():
        start_time = time.time()
        f()
        end_time = time.time()
        rtime = end_time - start_time
        print(rtime)
    return inner

index=calculate_time(index)
index()

这便是一个完整的装饰器了。
为了简化我们可以将代码:

index=calculate_time(index)

利用语法糖做如下简化

@calculate_time

利用形式如下:

@calculate_time
def index():
    time.sleep(2)

注意语法糖的应用需要在装饰器的定义后面,不然会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值