python--生成器协程运算
生成器
一、yield运行方式
我们定义一个如下的生成器:
def put_on(name):
print("Hi {}, 货物来了,准备搬到仓库!".format(name))
while True:
goods = yield
print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) p = put_on("bigberg") #输出
G:\python\install\python.exe G:/python/untitled/study4/test/double.py Process finished with exit code 0
当我们把一个函数通过yield转换成生成器,直接运行函数是不会出现结果返回的。因为此时函数已经是个生成器了,我们要通过next()来取得值,并且在遇到yield时再次跳出函数。
print(type(p)) #输出
<class 'generator'>
我们添加next()方法:
def put_on(name):
print("Hi {}, 货物来了,准备搬到仓库!".format(name))
while True:
goods = yield #遇到yield中断
print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) #中断后运行部分 p = put_on("bigberg")
p.__next__() #输出
Hi bigberg, 货物来了,准备搬到仓库!
此时函数中断在 goods = yield 的地方,当我们再次调用next()函数时,函数只会运行中断以后的内容,即上例中的yield下面部分。
我们再添加一个next():
def put_on(name):
print("Hi {}, 货物来了,准备搬到仓库!".format(name))
while True:
goods = yield
print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) p = put_on("bigberg")
p.__next__()
p.__next__() #输出
Hi bigberg, 货物来了,准备搬到仓库!
货物[None]已经被bigberg搬进仓库了。
我们可以第二次next()运行的是yield下面的部分内容,但是并没有给goods传值,所以货物是 None。
小结:
- 通过yield将函数转换为生成器,需要使用next()方法才能运行
- yield只是保留函数的中断状态,再次调用next()会执行yield后面的部分
- yield如果没有返回值,会返回一个None空值
二、send()传值
def put_on(name):
print("Hi {}, 货物来了,准备搬到仓库!".format(name))
while True:
goods = yield
print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) p = put_on("bigberg")
p.__next__()
p.send("瓜子") #输出
Hi bigberg, 货物来了,准备搬到仓库!
货物[瓜子]已经被bigberg搬进仓库了。
小结:
- __next__()只是调用这个yield,也可以说成是唤醒yield,但是不不会给yield传值。
- send()方法调用yield是,能给yield传值
- 使用send()函数之前必须使用__next__(),因为先要中断,当第二次调用时,才可传值。
def put_on(name):
print("Hi {}, 货物来了,准备搬到仓库!".format(name))
while True:
goods = yield
print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) p = put_on("bigberg")
p.__next__()
p.send("瓜子")
p.send("花生")
p.send("饼干")
p.send("牛奶") #多次调用send()
Hi bigberg, 货物来了,准备搬到仓库!
货物[瓜子]已经被bigberg搬进仓库了。
货物[花生]已经被bigberg搬进仓库了。
货物[饼干]已经被bigberg搬进仓库了。
货物[牛奶]已经被bigberg搬进仓库了。
三、单线程实现并行效果(协程)
import time def put_on(name):
print("Hi {}, 货物来了,准备搬到仓库!".format(name))
while True:
goods = yield
print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) def transfer(name):
p = put_on('A')
p2 = put_on('B')
p.__next__()
p2.__next__()
print("%s将货物送来了!"%name)
for i in range(5):
time.sleep(1)
print("%s递过来两件货物"%name)
p.send("瓜子")
p2.send("花生") transfer("bigberg") #输出
Hi A, 货物来了,准备搬到仓库!
Hi B, 货物来了,准备搬到仓库!
bigberg将货物送来了!
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
bigberg递过来两件货物
货物[瓜子]已经被A搬进仓库了。
货物[花生]已经被B搬进仓库了。
python--生成器协程运算的更多相关文章
- python生成器 协程
生成器 参考文章: 协程 gevent 生成器进阶 看个例子: def gg(): n='' i=0 while True: n=yield i #通过send传入到n if not n: pa ...
- python中和生成器协程相关的yield from之最详最强解释,一看就懂(四)
如果认真读过上文的朋友,应该已经明白了yield from实现的底层generator到caller的上传数据通道是什么了.本文重点讲yield from所实现的caller到coroutine的向下 ...
- python中和生成器协程相关yield from之最详最强解释,一看就懂(二)
一. 从列表中yield 语法形式:yield from <可迭代的对象实例> python中的列表是可迭代的, 如果想构造一个生成器逐一产生list中元素,按之前的yield语法,是在 ...
- python中和生成器协程相关的yield之最详最强解释,一看就懂(一)
yield是python中一个非常重要的关键词,所有迭代器都是yield实现的,学习python,如果不把这个yield的意思和用法彻底搞清楚,学习python的生成器,协程和异步io的时候,就会彻底 ...
- python gevent 协程
简介 没有切换开销.因为子程序切换不是线程切换,而是由程序自身控制,没有线程切换的开销,因此执行效率高, 不需要锁机制.因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断 ...
- 关于Python的协程问题总结
协程其实就是可以由程序自主控制的线程 在python里主要由yield 和yield from 控制,可以通过生成者消费者例子来理解协程 利用yield from 向生成器(协程)传送数据# 传统的生 ...
- {python之协程}一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二
python之协程 阅读目录 一 引子 二 协程介绍 三 Greenlet 四 Gevent介绍 五 Gevent之同步与异步 六 Gevent之应用举例一 七 Gevent之应用举例二 一 引子 本 ...
- 【Python】协程
协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B,B在 ...
- 深入理解Python中协程的应用机制: 使用纯Python来实现一个操作系统吧!!
本文参考:http://www.dabeaz.com/coroutines/ 作者:David Beazley 缘起: 本人最近在学习python的协程.偶然发现了David Beazley的co ...
- Python之协程(coroutine)
Python之协程(coroutine) 标签(空格分隔): Python进阶 coroutine和generator的区别 generator是数据的产生者.即它pull data 通过 itera ...
随机推荐
- c# dataGridView排序
一.对阿拉伯数字进行自定义排序: 简单有效方法: 1.该列的sortmode属性为auto...(一般默认) 2.比如首列序号,添加该列数据的时候直接添加int即可.切忌不要用string. obje ...
- python 读取blob
for num in range(76802): # if num == 0: # c[num] = imagedata[0:4] # d[num] = struct.unpack('i', c[nu ...
- VS2015做单元测试
1.安装测试插件 2.新建测试用例 这里就用课堂练习找水王 作例子 写一个类waterKing.h和waterKing.cpp //idList.h #pragma once #include< ...
- python __call__ 函数
__call__ Python中有一个有趣的语法,只要定义类型的时候,实现__call__函数,这个类型就成为可调用的. 换句话说,我们可以把这个类型的对象当作函数来使用,相当于 重载了括号运算符. ...
- java的reflection
Reflection是Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性.例如,使用它能获得 Java 类中 ...
- Swift-存储属性,计算属性,类属性
//类的属性定义 class Student: NSObject { // 定义属性 // 定义存储属性 var age : Int = var name :String? var mathScore ...
- css选择器和新增UI样式总结
经过两天的学习,初步对css3选择器和新增UI样式有了进一步的理解.
- 奇异值分解(SVD)原理详解及推导(转载)
转载请声明出处http://blog.csdn.net/zhongkejingwang/article/details/43053513 在网上看到有很多文章介绍SVD的,讲的也都不错,但是感觉还是有 ...
- PHP执行原理
简单解释:PHP执行原理 客户端向服务器发送一个请求,如果请求的是一个HTML页面,服务器直接将HTML页面发送到客户端给浏览器解析,如果请求的是PHP页面,则服务器会运行PHP页面然后生成标准的HT ...
- 常用的Redis客户端的并发模型(转)
伪代码模型 # get lock : timestamp = current Unix time + lock = SETNX lock.foo timestamp or (now() > ...