def demo_input_and_output():

input = yield 'what is the input?'

yield 'input is: %s' % input

gen = demo_input_and_output()

print(gen.next())

print(gen.send(42))

这段代码演示了 python generator 的功能。可以看到 yield 同时做了两个操作,一个是往外发数据 "waht is the input",同时做的操作是往里收数据 input。而且这个接收数据的操作是一个阻塞的操作,如果外部没有调用 next() (也就是往里传递None),或者调用send(42)(也就是往里传递42这个值),那么这个阻塞的操作就会一直等待下去。

也就是说 python 的 generator 自带了一个对外通信的 channel,用于收发消息。用 go 模拟 python 的 generator 的话写起来就是这样的

package main

import "fmt"

func demoInputAndOutput(channel chan string) {

channel <- "what is my input?"

input := <- channel

channel <- fmt.Sprintf("input is: %s", input)

}

func main() {

channel := make(chan string)

go demoInputAndOutput(channel)

fmt.Println(<- channel)

channel <- "42"

fmt.Println(<- channel)

}

这段代码和 python 版本基本上等价。隐含的 channel 在 go 版本里变成显式的了。yield 变成了 channel <- 操作,同时立马做了一个 <- channel 的阻塞读操作。这也就是 yield 的本质吧。

go 的 channel 也可以当成 iterator 被 for 循环使用:

package main

import "fmt"

func someGenerator() <-chan string {

channel := make(chan string)

go func() {

channel <- "a"

fmt.Println("after a")

channel <- "c"

fmt.Println("after c")

channel <- "b"

fmt.Println("after b")

close(channel)

}()

return channel

}

func main() {

channel := someGenerator()

for val := range channel {

fmt.Println(val)

}

}

和 python 的 yield 不同,这里的 channel <- 不等价于 yield,它会往下执行直到阻塞。效果是

after a

a

c

after c

after b

b

这和预期的顺序不一样。这里没有把 after a after c after b 都打印出来是因为 channel 默认只有一个元素的buffer,所以写入了一个就阻塞了。如果增大 buffer,那么就有效果了

make(chan string, 10)

输出变成了:

after a

after c

after b

a

c

b

可见 goroutine 就好象一个独立的线程一样自己和自己玩去了,不用等待被执行。如果要模拟 yield 就要加上显示的同步操作(从 channel 里阻塞读取信号):

package main

import "fmt"

func someGenerator() chan string {

channel := make(chan string)

go func() {

channel <- "a"

<- channel

fmt.Println("after a")

channel <- "c"

<- channel

fmt.Println("after c")

channel <- "b"

<- channel

fmt.Println("after b")

close(channel)

}()

return channel

}

func main() {

channel := someGenerator()

for val := range channel {

fmt.Println(val)

channel <- ""

}

}

输出的结果就是

a

after a

c

after c

b

after b

到这里我们可以看到,python 的 generator 就好象是 golang 的 goroutine 带了一个无buffer的channel。这样导致每次yield一个值,都会产生一次协程上下文切换。虽然协程上下文切换很廉价,但是也不是没有成本。像 goroutine 的 buffered channel 这样的设计,可以让一个 goroutine 一次性多产生一些输出再阻塞等待,而不是产生一个输出就阻塞等待一下,再产生另外一个输出。golang rocks!

python golang 小工具_使用Go语言简单模拟Python的生成器相关推荐

  1. python制作小工具_利用Python制作翻译小工具

    话不多说,直接上代码. Component文件: # coding:utf-8 from tkinter import * from tkinter import ttk from tkinter i ...

  2. 如何用python写小工具_用python写一个录音小工具

    Python的paramiko,wxPython库的应用 Sound eXchange 命令行 需求 最近在给一个做语音识别的项目做QA工作.众所周知,此类人工智能方面的项目都需要一些数据收集的工作. ...

  3. python整人小程序_一个可以套路别人的python小程序实例代码

    先简要介绍一下程序. 程序是使用pycharm工具,python语言所写.程序包括客户端 client.py 和服务器端 server.py 两部分,利用了python中的socket包. 咳咳,使用 ...

  4. python抓包工具_「docker实战篇」python的docker爬虫技术-fiddler抓包软件详细配置(七)...

    挑选常用的功能给各位老铁介绍下. fiddler第一次进入fiddlerfiddler会请求fiddler的官网,检查更新操作布局分布 工具栏File -capture traffic开启爬虫File ...

  5. python 处理数据小工具_用Python这个小工具,一次性把论文作图与数据处理全部搞定!...

    原标题:用Python这个小工具,一次性把论文作图与数据处理全部搞定! 一入科研深似海-- 随着大学纷纷开学,"防脱发用生姜还是黑芝麻?", 研究僧们又开始为自己所剩无几的头发发愁 ...

  6. python自动翻译小工具_Python实现翻译小工具

    一.背景 利用Requests模块获取有道词典web页面的post信息,BeautifulSoup来获取需要的内容,通过tkinter模块生成gui界面. 二.代码 git源码地址 Python实现翻 ...

  7. 用Python编写小工具下载OSM路网数据

    文章来源于Python大数据分析,作者费弗里 本文对应脚本已上传至Github仓库: https://github.com/CNFeffery/DataScienceStudyNotes[1] 1 简 ...

  8. 有关Python的小工具 - picture

    有关Python的小工具 - picture 读取图片 通过cv2.imread读取图片 通过cv2.imread读取比特流 通过Image.open读取图片 通过io.BytesIO读取比特流 保存 ...

  9. python模块版本管理工具_【转】Python包管理工具

    Python 包管理工具解惑 本站文章除注明转载外,均为本站原创或者翻译. 本站文章欢迎各种形式的转载,但请18岁以上的转载者注明文章出处,尊重我的劳动,也尊重你的智商: 本站部分原创和翻译文章提供m ...

最新文章

  1. 22年前被嘲养猪的北大学子,如今带领200多户住上别墅,90后研究生也跟他加入养猪行列...
  2. 移动端1px像素的设置?
  3. Leetcode 144. 二叉树的前序遍历 解题思路及C++实现
  4. K-均值聚类算法对未标注数据分组(1)
  5. Python控制鼠标和键盘-PyAutoGUI用法详解
  6. 一些PHP性能优化汇总
  7. ssl1344-Knights【最大独立集,最大匹配,图论】
  8. VMware Workstation 运行出现“由于应用程序配置不正确,应用程序未能启动。重新安装应用程序可能会纠正这个问题”解决方案
  9. C++中size_type类型详解
  10. 根据父类id查询所有的父级_031、组函数和子查询
  11. 瓜子二手车在 Dubbo 版本升级、多机房方案方面的思考和实践
  12. 【转】为什么要用GIT而不是SVN
  13. 数据库 Oracle监听实例详解
  14. 保研经历总结-清华大学计算机系
  15. 关于百度【搜索RefererAPI】开放接口根据eqid查询【搜索关键字】的实现
  16. 优质的草图大师素材 草图66!
  17. Linux(1) 概要、安装 、文件系统基本认知
  18. canvas生成圆形图章(名称紧凑和散开)
  19. javaMap集合 详解
  20. S32K系列之ADC

热门文章

  1. 新能源维修和计算机应用哪个好,在买新能源车之前 这些事你应该先知道
  2. 佳恩半导体完成数千万A轮融资
  3. 驯龙大师稳了!iQOO Neo6游戏实测:两款手游均接近满帧
  4. 呷哺呷哺:预期2021年净亏损约2.75亿元至2.95亿元
  5. 董明珠上榜中国杰出商界女性100
  6. 宁德时代拟再投240亿元扩产宜宾基地
  7. 花51万请明星和网红带货仅卖5000元,法院这样判了...
  8. 千万别让海底捞知道你的生日
  9. 上海新阳半导体收到ASML-1400光刻机 将用于研发193nm ArF光刻胶
  10. 股市太火 !“牛市”搜索热度暴涨9倍:80后疯狂开户