文档章节

python yield表达式总结(generator)

flyking
 flyking
发布于 2013/09/11 09:56
字数 1057
阅读 976
收藏 9

2014-3-4迭代器必须在类中实现,因为要实现 next, __iter__ 方法

一般在next里满足的停止迭代条件后要使用 raise StopIteration 来结束迭代,当然了,自定义异常抛出也行.

http://hi.baidu.com/rails7/item/5b033a437a8f75d2c0a59241

迭代器(对象)版本

#!/usr/bin/env python 
# -*- coding: utf-8 -*-

class Fib(object): 
    a = 0
    b = 1
        
    def next(self): 
        self.a, self.b = self.b, self.a + self.b
        # 超过10000后停止迭代 
        if self.a > 10000:
            raise StopIteration
        return self.a 
        
    def __iter__(self): 
        return self
        
        
fibs = Fib() 

for f in fibs: 
    print f

生成器(函数)版本

#!/usr/bin/env python 
# -*- coding: utf-8 -*-

def fib(): 
    a, b = 0, 1
    while True: 
        a, b = b, a+b 
        if a > 1000 and a < 5000:
            yield "1000 to 5000 don`t display"
            continue
        if a > 10000:
            raise StopIteration
        yield a 
        
for f in fib(): 
    print f

---------------------------

关于yield表达式(generator) 疑惑了很久, 昨晚坐公交翻看了 Manuals总结如下:

例子党, 直接上代码..

# -*- coding: utf-8 -*-

"""例子1
一个函数含有yield表达式 这个函数就不是普通函数,而是生成器(generator)
"""
def gen():
    print "start"                 #*0
    m = yield 2                   #*1 # yield意思是产生, 此表示产生2 就是调用可以返回2 (当然,返回是有条件的)
    print m                       #*2 
    n = yield 3                   #*3
    print n                       #*4

    try:                          #*5
        print "end"               #*6
    except StopIteration as e:    #*7
        print e                   #*8
        # raise e


# 先说明yield表达式, yield有点像<前置操作符>, 跟在表达式前面,用于把表达式的值返回给调用者, (yield 2)本身的值赋给m

g = gen()
""" result:
<generator object f at 0x01228EE0>
"""
#↑>>> 可以看出是一个generator, 此时并没有执行 *0和*1行
g.send(3)
""" result:
TypeError: can't send non-None value to a just-started generator
"""
#↑>>> 开始生成器不能send非空值
g.send(None) # 住: g.next()相当于g.send(None) 本人习惯用send而不是next
""" result:
start
2 #此时函数(生成器)返回了2(就是yield后的,此时你可以理解为yield相当于return,但是返回后暂停了执行)
"""
# 此时函数挂起(让出cpu使用权)并保持状态,直到遇到下一个next/send 
# g.send(None) 调用者把None这个消息send给上一个yield表达式,由于第一次调用,没有上一个yield.
# 到目前为止, 调用了一次send(None) 总结一下, 上面说到保持状态:目前函数运行到*1行并挂起
print g.send(5)
""" result:
5
3 #和上面一样,第二个yield生成(返回)的值为3
"""
# 此时函数从*1行后继续执行 通过调用g.send(5),调用者把5这个消息send给上一个yield表达式(yield 2) 既:(yield 2)这个整体的值,此时m = 5
# 到目前为止, 调用了一次send(None),一次send(5) 总结一下, 上面说到保持状态:1.此时的状态是:m(既yield 2这个整体的结果值)被调用者发送消息赋值为5 2.目前函数运行到*3行并挂起
print g.send(6)
#result:
# 6
# end
# StopIteration
# 此时函数从*3行后继续执行 通过调用g.send(6),调用者把6这个消息send给了上一个yield表达式(yield 3) 既:(yield 3)这个整体的值,此时n = 6
# 继续往下执行,由于没有了遇不到yield,所有会出现 StopIteration 异常而结束

# 到目前为止,生成器函数运行结束,由于生成器会记住状态, 再调用send/next还会出现StopIteration异常

# 通过生成器, 调用者和函数内部可以交互消息, 暂停执行, 可用同步代码处理异步, 如:tornado的 @gen修饰器, twisted的@inlineCallback修饰器...

"""例子2
在for循环迭代过程中, 系统自动回调用next方法,不用显示调用
"""
def foo(list2gen):
    for item in list2gen:
        yield item # 此时 yield有点像调用一次而不结束而是暂停执行的return ,这里的好处类似iterator, 要给你生成给你一个,而不是像list, 一下都给你,占用内存大

l = [2,3,4]

for i in foo(l): # 这里foo把l变成了生成器
    print i

# result:
# 2
# 3
# 4

"""例子3
一个模拟无穷列表的情况(此处必须用生成器)
"""
def g():
    n = 0
    while True:
        yield n
        n += 1

# 哈哈,无限生成 递增数, 一直打印, 直到(内存耗尽?)
for i in g():
    print i

© 著作权归作者所有

flyking
粉丝 64
博文 218
码字总数 75579
作品 0
东城
程序员
私信 提问
Iterator, Generator 与 Yield

Iterator Iterator(迭代器) 是一种常见的对象,它允许调用者方便的遍历该对象中的元素,广泛的运用于多种编程语言,如 Python, Java 和 Ruby 等。以 Python 为例,Iterator 需要实现两种方法...

koala bear
2016/10/18
0
0
python中的yield使用详解

yield是python的一个关键字,刚接触python的时候对这个关键字一知半解,掌握之后才发现这关键字有大用,本文将对yield的使用方法好好梳理一番。 1 使用yield创建生成器 在python中,生成器是...

Keybord_dancer
09/29
0
0
Python 3.5的async和await特性(PEP492翻译)

原因: 1,coroutine容易与正常的generators弄混 2,一个function是否为coroutine由函数体内是否有yield 或者yield from 决定,这不科学。 3,如果在语法上允许yield的地方才能进行异步调用,...

junanhonglei
2015/06/23
2.8K
3
深入理解 Python yield

yield的英文单词意思是生产,刚接触Python的时候感到非常困惑,一直没弄明白yield的用法。一直到稀里糊涂的看完了廖雪峰的python博客也没彻底明白。 有一次不小心看到了这个文章,是转载的,...

世外大帝
2017/12/27
0
0
基于python yield机制的异步操作同步化编程模型

又一个milestone即将结束,有了些许的时间总结研发过程中的点滴心得,今天总结下如何在编写python代码时对异步操作进行同步化模拟,从而提高代码的可读性和可扩展性。 游戏引擎一般都采用分布...

窗台跳舞的猫
2013/12/12
3.9K
9

没有更多内容

加载失败,请刷新页面

加载更多

Nginx 快速安装详解

一、Nginx Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,同时也提供了IMAP/POP3/SMTP服务。Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамбле...

网络小虾米
28分钟前
4
0
技术分享 | slave_relay_log_info 表认知的一些展开

作者:胡呈清 slave_relay_log_info 表是这样的: mysql> select * from mysql.slave_relay_log_info\G *************************** 1. row *************************** Number_of_lin......

爱可生
31分钟前
3
0
nginx配置http访问自动跳转到https

server {listen 80;server_name www.域名.com;rewrite ^(.*) https://$server_name$1 permanent;}server {listen 443;server_name www.域名.com;root /home/www;ssl on;......

很好亦平凡ms
31分钟前
4
0
SpreadJS:一款中国研发的类Excel开发工具,功能涵盖Excel的 95% 以上

Excel 作为一款深受用户喜爱的电子表格工具,借助其直观的界面、出色的计算性能、数据分析和图表,已经成为数据统计领域不可或缺的软件之一。 基于Excel对数据处理与分析的卓越表现,把Excel...

葡萄城技术团队
31分钟前
3
0
用javafx框架tornadofx做了个天气预报的程序

class WeatherApp : App(WeatherView::class)class WeatherView : View("十五天天气预报") { val weatherVM: WeatherViewModel by inject() val controller: WeatherController by......

oschina4cyy
35分钟前
4
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部