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)
注意语法糖的应用需要在装饰器的定义后面,不然会报错。