一、什么是生成器?

使用了yield函数 就被称之为生成器,生成器是一个返回迭代器的函数,说白了生成器就是迭代器,只能用于迭代操作。

不懂?没关系,下面就一个​斐波那契数列​为例来进行讲解

依靠简单循环生成的一个“斐波那契数列”

a,b = 0,1                                                                                                                 

while a<100:
a,b = b,a+b
print(a)

程序运行结果如下:

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_生成器

这段代码是通过非递归的方法实现斐波那契数列,接下来,我就用生成器的方式实现斐波那契数列

import sys

def fibonacci(n): #生成迭代器函数
a,b,count = 0,1,0
while True:
if(count > n):
return n
yield a #使用生成器(迭代器,当程序遇到yield函数时,会暂停并保存当前所有的信息——
# 并返回yield的值,然后程序运行到next()函数时,并从当前位置继续运行 a,b = b,a+b count = count + 1f = fibonacci(10) #f是一个迭代器,由生成器生成,10为递归结束的信号

while True:
try:
print(next(f),end=" ")
except:
sys.exit()

程序的运行结果如下:

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_迭代器_02

二、什么是迭代器?

迭代是Python众多强大的功能之一,它是访问集合元素的一种方式,它是可以记住遍历对象的位置,这点和for循环中enumerate关键字有点相似,不过enumerate其实是记住数组,元组,列表等等下标的一个函数。但是迭代器会从集合中的第一个元素开始访问,一直到最后一个元素,迭代器只能往前不会后退。

迭代器有两种方法:


  • iter()
  • next()

字符串,列表,元组,字典(键值)的对象都可以创建迭代器,下面是几个简单得实例

list = [2,1,4,6]

It = iter(list)
for i in It:
print(i,end=" ")

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_生成器_03

同理,也可以使用​next() ​函数

import sys
list = [11,22,33,454]It = iter(list)

while True:
try:
print(next(It)) except:
sys.exit()

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_斐波那契数列_04

三、 什么是装饰器?

前面讲了生成器,迭代器怎么又来了个​装饰器​ ,装饰器的功能还是很强大的,它能够不改变函数本地的结构,却可以给函数增加额外的功能,下面就以实例来讲解

1、我们先用函数打印一句话

def sayHi():    print("Hi,man")
#sayHi() #这是函数调用的方法
#还有另一种输出的方法x = sayHi
x()

现在我们希望可以在“sayHi”函数之前输入一句话,这种在代码运行期间动态增加功能的方式,称之为装饰器,下面我们就改改上面这个代码:

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_生成器_05

2、改一改

def sayHello(func):
def inner():
print("Hello,I am Gorit")
return func
return inner()

def sayHi():
print("Hi,man")

x = sayHello(sayHi)
s()

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_生成器_06

这样的效果看起来不是很好,我们每次都要加个功能都要使用

x = sayHello(sayHi)
s()

对于这种情况,Python提供了语法糖 —— “@”,这样我们就可以轻松的输出我们想要的语句

3、有了语法糖的加入,程序变得更简单

def sayHello(func):
def inner():
print("Hello,I am Gorit")
return func
return inner()

@sayHellod
ef sayHi():
print("Hi,man")
sayHi()

没有5年测开经验,还真说不清Python生成器、迭代器、装饰器_生成器_07

在上面的代码中,我们定义了一个​sayHello(func)函数​,sayHello接受参数func,里面又内嵌一个 inner()函数,然后输出(“Hello,I am Gorit”,之后返回 func 参数,(也就是我们要传入的参数),然后再返回inner函数,然后我们发现这就是一个封闭的函数,也称为闭包函数

然后我们再sayHi()之前加入 @sayHello, 其目的使程序运行到这里会调用装饰器函数"sayHello",并把被装饰的函数"sayHi"作为参数传入,此时"sayHi"是指向sayHello.inner 的地址,然后再调用sayHi时,实则是调用sayHello.inner。