yield

python yield关键词使用总结

可紊 提交于 2019-12-01 09:54:03
python yield 关键词使用总结 by: 授客 QQ : 1033553122 测试环境 win10 python 3.5 yield功能简介 简单来说,yield 的作用就是把一个函数变成一个 generator,带有 yield 的函数不再是一个普通函数,Python 解释器会将其视为一个 generator 代码演示 例子1: 输出斐波那契數列前 N 个数 #!/usr/bin/env python # -*- coding:utf-8 -*- __author__ = 'shouke' def fab(max): n, a, b = 0, 0, 1 result = [] while n < max: result.append(b) a, b = b, a + b n = n + 1 return result for n in fab(5): print(n) 以上代码虽然可以满足需求,但是存在的问题:该函数在运行中占用的内存会随着参数 max 的增大而增大,如果要控制内存占用,最好不要用 List 改进 使用yield def fab(max): n, a, b = 0, 0, 1 while n < max: yield b # 使用 yield a, b = b, a + b n = n + 1 for n in fab(5): print(n) 例子2

Implementing “Generator” support in a custom language

旧时模样 提交于 2019-12-01 08:18:14
I've got a bit of fettish for language design and I'm currently playing around with my own hobby language. ( http://rogeralsing.com/2010/04/14/playing-with-plastic/ ) One thing that really makes my mind bleed is "generators" and the "yield" keyword. I know C# uses AST transformation to transform enumerator methods into statemachines. But how does it work in other languages? Is there any way to get generator support in a language w/o AST transformation? e.g. Does languages like Python or Ruby resort to AST transformations to solve this to? (The question is how generators are implemented under

yield和send

末鹿安然 提交于 2019-12-01 07:43:18
前面已经说过yield的作用: 1、类似于return每次返回一个值 2、代码块(函数)暂停在yield的位置,下次调用时继续执行yield之后和之前的代码块 3、通过next(f)获取到yield的返回值 send的作用其实和yield类似: 1、类似于return每次返回一个值 2、代码块(函数)暂停在yield的位置,下次调用时继续执行yield之后和之前的代码块 3、send(x)可以理解为next(x),也就是把send的结果当做yield的返回值给next来获取 有点拗口,下面直接看例子: for i in range(8): try: print(next(a)) except StopIteration as e: print(e) break 执行结果: ... 1 1 None ... 2 2 None done 再看个例子: for i in range(8): try: if i == 1: a.send(8) # send(x)等同于吧yield之后和之前的代码执行一遍,并返回x的值给next(a) print(next(a)) # 这里会继续调用next,继续执行yield之后的代码直到yield else: print(next(a)) except StopIteration as e: print(e) break 执行结果: ... 1 1 8

python协程 示例

£可爱£侵袭症+ 提交于 2019-12-01 07:26:07
协程 1.协程 又称微线程 是一种轻量级线程 携程有自己的寄存器 上下文 和栈 携程能保留上一次调用时的状态 2.协程优点和缺点 : 1.无需线程上下文切换的开销 2.无需原子操作锁定及同步的开销 3.高并发 高扩展性 低成本 缺点: 1.无法利用多核资源 2.阻塞操作会阻塞整个程序 python利用 yield来达到携程效果,:先看下 关于yield的两个用法 ( yield from 是python3 的方法) def aa(): for i in 'ab': yield i for i2 in range(0, 3): yield i2 print list(aa()) 》》》 ['a', 'b', 0, 1, 2] def bb(): yield from 'ab' yield from range(3) print (list(bb())) 》》》 ['a', 'b', 0, 1, 2] 利用yield 来写一个经典的生产 消费者: def consumer(name):# 消费者 print("--->starting") while True: new_baozi = yield print("[%s] is eating baozi %s" % (name, new_baozi)) def producer(): # r = con.__next__() r =

C# yield关键字

独自空忆成欢 提交于 2019-12-01 07:26:05
原文: C# yield关键字 关于yield关键字,网上有很多文章介绍了,但是看了之后,虽然明白了"哦,原来是这么回事",但是在日常开发中并没有真正的用起来,所以,写此一篇,介绍一下在真正的项目中怎么使用这个关键字。 开始我的正文介绍之前,可以先看一下微软的官方文档是怎么介绍yield关键字的,传送门: https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/yield 在这里我新建了一个控制台程序,用于输出斐波那契数列,代码如下:我们直接在Main方法中输出斐波那契数列,这个也没有什么问题,很完美,但是考虑到实际开发中不可能把所有的处理都写在程序入口,所以我们考虑对这段代码封装一个方法V1 static void Main(string[] args) {int a = 0, b = 1, c = 0; for (int i = 0; i < 10; i++) { Console.WriteLine("{0}", b); c = a + b; a = b; b = c; } //V1(10); //foreach (var i in V2(10)) //{ // Console.WriteLine(i); //} //foreach (var i in V3(10)) //{ //

3-1 协程介绍

送分小仙女□ 提交于 2019-12-01 06:48:58
一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去执行其他的任务(切换由操作系统强制控制),一种情况是该任务发生了阻塞,另外一种情况是该任务计算的时间过长或有一个优先级更高的程序替代了它 ps:在介绍进程理论时,提及进程的三种执行状态,而线程才是执行单位,所以也可以将上图理解为线程的三种状态 一:其中第二种情况并不能提升效率,只是为了让cpu能够雨露均沾,实现看起来所有任务都被“同时”执行的效果,如果多个任务都是纯计算的,这种切换反而会降低效率。为此我们可以基于yield来验证。yield本身就是一种在单线程下可以保存任务运行状态的方法,我们来简单复习一下: 1 yiled可以保存状态,yield的状态保存与操作系统的保存线程状态很像,但是yield是代码级别控制的,更轻量级 2 send可以把一个函数的结果传给另外一个函数,以此实现单线程内程序之间的切换 单纯地切换反而会降低运行效率 #串行执行 import time def consumer(res): '''任务1:接收数据,处理数据''' pass def producer(): '''任务2:生产数据''' res=[] for i in range(10000000):

在 PHP 中使用 Promise + co/yield 协程

扶醉桌前 提交于 2019-12-01 06:21:49
为什么需要异步方式 一个函数执行之后,在它后面顺序编写的代码中,如果能够直接使用它的返回结果或者它修改之后的引用参数,那么我们通常认为该函数是同步的。 而如果一个函数的执行结果或者其修改的引用参数,需要通过设置回调函数或者回调事件的方式来获取,而在其后顺序编写的代码中无法直接获取的话,那么我们通常认为这样的函数是异步的。 PHP 提供的大部分函数都是同步的。通常我们会有一个误解,那就是容易把同步和阻塞当成同一个概念,但实际上同步代码不一定都是阻塞的,只是同步代码对阻塞天然友好,当同步代码和阻塞结合时,代码通常是简单易懂的。 阻塞带来的问题是当前线程(或进程)会陷入等待,一直等到阻塞结束,这样就会造成线程(或进程)资源的浪费。所以,通常认为阻塞是不够高效的。 但是如果要编写非阻塞代码,使用同步方式会变得有些复杂,且不够灵活。同步方式的非阻塞代码通常会使用 select 模式,例如 curl_multi_select , stream_select , socket_select 等就是 PHP 中提供的一些典型的 select 模式的函数。 我们说它复杂且不够灵活是有理由的,例如使用上面的 select 模式编写同步的非阻塞代码时,我们需要先构造一个并发任务的列表,之后手动构造循环来执行这些并发的任务,在循环开始之后,虽然这几个任务可以并发

Implementing “Generator” support in a custom language

 ̄綄美尐妖づ 提交于 2019-12-01 05:47:40
问题 I've got a bit of fettish for language design and I'm currently playing around with my own hobby language. (http://rogeralsing.com/2010/04/14/playing-with-plastic/) One thing that really makes my mind bleed is "generators" and the "yield" keyword. I know C# uses AST transformation to transform enumerator methods into statemachines. But how does it work in other languages? Is there any way to get generator support in a language w/o AST transformation? e.g. Does languages like Python or Ruby

Python (yield): all paths from leaves to root in a tree

天大地大妈咪最大 提交于 2019-12-01 05:33:25
I want to generate all paths from every leaf to root in a tree. I'd like to do that with generators, to save memory (tree can be big). Here's my code: def paths(self, acc=[]): if self.is_leaf(): yield [self.node]+acc for child in self.children: child.paths([self.node]+acc) But it doesn't work. Why? Invoked at root, it traverses the tree from top to bottom, collecting nodes in "acc". "acc" should be returned in every leaf... is_leaf() is true if self.children is empty. This code only yields leaves that are (immediate) children of the root. The other ones get visited, they yield to the upper

12 函数进阶---生成器

人走茶凉 提交于 2019-12-01 05:23:49
列表生成式 >>> a = [i+1 for i in range(10)] >>> a [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 生成器 通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素占用的空间都白白浪费了。 所以,如果列表元素可以按照某种算法推算出来,那我们是否可以在循环的过程中不断推算出后续的元素呢?这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器:generator。 要创建一个generator,有很多种方法。第一种方法很简单,只要把一个列表生成式的[]改成(),就创建了一个generator: >>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> g <generator object <genexpr> at 0x1022ef630> 创建L和g的区别仅在于最外层的[]和(),L是一个list,而g是一个generator。我们可以直接打印出list的每一个元素