栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

详解:什么是协议,及对生成器,迭代器,协程的理解

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

详解:什么是协议,及对生成器,迭代器,协程的理解

“协议”

(protocol)的意思,其实协议是用来“规范/标准化”你“创造的东西”的。比如,你开天辟地的发明了一种东西叫做“我爱你却不能在一起”,你给小沛说:“小沛,给我发一个我爱你却不能在一起过来”,如果小沛不知道啥叫“我爱你却不能在一起”,那么小沛会直接懵逼的。这时候你就要定一个“协议”如下:

1, "我爱你却不能在一起"一共有10个字

2, "我爱你却不能在一起"开头和结尾都是"#"号 (占两个字)

3, "我爱你却不能在一起"最后二位是"bp"

4, 其他不限制

那么我们根据这个协议,可以很轻易的构造出“我爱你却不能在一起”来:#0629bp# 或者 #0819bp#

同样,我们根据这份协议,就可以用来检测你得到的是不是“我爱你却不能在一起”,#3141bp# -> 是,#1314bp!-> 不是

迭代(iteration)

迭代就是重复的的既定的任务,直到完成。所以,为了完成迭代,我们需要一个迭代器!

迭代器协议 iterator protocol

从前有个人发明了迭代器,为了让大家明白什么是迭代器,他就写了这个协议,那么协议的内容简而言之就是一句话:如果一个对象包括一个叫"next"(python3 为__next__)的方法,那么这个对象就叫做“迭代器”。

可迭代协议 iterable protocol

在python中,为了使一个”对象“可迭代:

1,这个迭代器必须同时包含另一个方法叫做“__iter__”

2,这个"__iter__"方法还得返回一个”迭代器“(可迭代)

生成器generator

生成器的出现,就是为了简化创建迭代器的繁杂,同时又要保证逻辑的清晰,说到底生成器就是为了更方便我们使用迭代器而生的,生成器的特性如下:

1, 生成器的样子就是一个普通的函数,只不过return关键词被yield取代了

2, 当调用这个“函数”的时候,它会立即返回一个迭代器,而不立即执行函数内容,直到调用其返回迭代器的next方法是才开始执行,直到遇到yield语句暂停。

3, 继续调用生成器返回的迭代器的next方法,恢复函数执行,直到再次遇到yield语句

4, 如此反复,一直到遇到StopIteration

看如下例子:

def gFun():

    print('before wp')

    yield 'wp'

    print('after wp')

a = gFun() # 调用生成器函数,返回一个迭代器并赋给a

print(a) # 得到一个生成器对象(迭代器)

print(a.__next__())

# before wp# wp print(a.__next__())

# after wp# StopIteration

同时因为调用生成器函数返回的是一个迭代器,所以我们可以使用for..in语法糖对其进行迭代操作:

a = gFun()for x in a:

    print(x)

迭代返回了before wp, wp, after wp

def gen():

    for i in range(10):

        yield i

复制代码

这里yield的作用就相当于return,这个函数就是顺序地返回[0,10)的之间的自然数,可以通过next()或使用for循环来遍历。

当程序遇到yield关键字时,这个生成器函数就返回了,直到再次执行了next()函数,它就会从上次函数返回的执行点继续执行,即yield退出时保存了函数执行的位置、变量等信息,再次执行时,就从这个yield退出的地方继续往下执行。

在Python中利用生成器的这些特点可以实现协程。协程可以理解为一个轻量级的线程,它相对于线程处理高并发场景有很多优势。

从 generator对象获取值

为了从 generator 对象获取值,我们可以使用 for loop、next() 或者 list() 方法。

for loop 方法:

def odd_numbers(n):

    for x in range(n):

        if (x % 2) == 1:

            yield x

num = odd_numbers(10)

for i in num:

    print(i)

list()方法

def odd_numbers(n):

    for x in range(n):

        if (x % 2) == 1:

            yield x

num = odd_numbers(10)for i in list(num):

    print(i)

generator 对象只能被遍历一次

generator 对象只能被遍历一次,当我们再次使用时, generator 对象为空。

yield vs. return

包含 yield 的函数在被调用时,返回一个 generator 对象给调用者,只有在遍历对象时,函数的代码才会被执行。而函数中的 return 返回一个值给调用者。

 总结:
  • 和 return 关键字返回一个值给调用者不同的是,包含 yield 关键字的函数返回一个 generator 对象给调用者。
  • 返回的 generator 对象在使用过一次后便不再可以使用,如果要获取值,需要遍历 generator 对象。
  • 可以使用 for loop、next() 或者 list() 方法从 generator 对象获取值。
  • yield 和 return 的最大区别是,yield 返回一个 generator 给调用者,而 return 返回一个值给调用者。
  • 使用 yield 时,不会将值存储在内存中,这在处理的数据量很大时,比较有优势。
  • yield from 后面加上可迭代对象,可以把可迭代对象里的每个元素一个一个的 yield 出来,对比 yield 来说代码更加简洁,结构更加清晰。

协程是什么?

和 python 中的多线程(threading)一样,协程也是实现并发(concurrent)的一种方式,而在多线程中,各个线程之间何时切换、如何切换则是由系统自行处理,所以可能会造成一些不可控的现象发生,如中断了不该中断的重要线程或中途产生了不合理的数据等。而在协程中,不存在被中断一说,只有通过 yield 或 yield from 主动释放 CPU 资源,让步给其他协程,以此实现多线程的并发。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/344426.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号