Python中幽灵般的yield

原创 2016年08月28日 22:09:07

Python中幽灵般的yield

Python语言容易上手,偶尔也容易伤手,比如yield的用法。

这篇短文希望用简单的例子把yield的本质讲清楚,只是希望而已,万一讲不清楚,你可以用红包砸我~,:-x
直接说本文最重要的一句话:

python函数定义里用了yield就会把函数变为生成器。

例子#1 - 正常函数定义、调用

代码 try.py:
定义一个函数func,然后调用它,该函数返回1

#!/usr/bin/env python

def func():
    print ("func() started")
    return 1
    print ("func() ended")

g = func()
print "g = ", g

输出结果:

$ ./try.py
func() started
g =  1

这个没什么需要解释的。

例子#2 - 把例子#1里函数定义的return改成yield

#!/usr/bin/env python

def func():
    print ("func() started")
    yield 1
    print ("func() ended")

g = func()
print "g = ", g

输出结果:

$ ./try.py
g =  <generator object func at 0x10ccbcaa0>
  • 发现没?func这个“函数”竟然没有被调用!func的返回结果g的类型变成了生成器(generator)对象。

  • 因为“函数”func的定义里用了yield,导致func的类型不再是函数,而是变成了生成器类型定义,这时候“调用”func等于创建一个generator对象g,并不会执行里面的代码。

说明:
  • “函数定义”里一旦用了yield,就不再表示定义函数,而是变成定义生成器类型。这是动态类型语言python的特点。
  • 另外,“函数”定义里有return语句就是函数,有yield就是生成器,return和yield不能同时使用,要么你是定义函数,要么你是定义生成器,只能二选一。

  • 理解了yield必然导致生成器,就抓住了yield的本质,要运行生成器func里的代码就必须对它的对象进行遍历。

  • 生成器是只能遍历一次的迭代器,而常用的列表是可以重复从头多次遍历的,生成器遍历到尾部就不能再从头遍历了。

最后例子 - 遍历yield定义的生成器

#!/usr/bin/env python

def func():
    print ("func() started")
    for i in range(0,3):
        yield i #每次到这里都生成一个迭代元素
    print ("func() ended")

g = func() #这里不会执行func里的代码,只是创建了一个对象(generator对象)
print "g = ", g
for val in g: #遍历生成器,执行func里生成一个个迭代元素的代码,等价于执行了func里面的代码
    print "    val=", val

输出结果:

$ ./try.py
g =  <generator object func at 0x10a6e2aa0>
func() started
    val= 0 #生成的一个元素
    val= 1 #生成的一个元素
    val= 2 #生成的一个元素
func() ended #遍历的时候扫过这一行,所以它执行到了,但是它后面没有生成的元素了,到尾部了

相关文章推荐

Python中yield关键字与迭代器

本文主要是参考网络文章所作的一些学习笔记,谈不上原创,主要学习的文章如下所示:     http://www.ibm.com/developerworks/cn/opensource/os-cn...
  • sruru
  • sruru
  • 2013年02月20日 16:19
  • 1471

Python Generators(生成器)——yield关键字

转自:http://blog.csdn.net/scelong/article/details/6969276 生成器是这样一个函数,它记住上一次返回时在函数体中的位置。对生成器函数...
  • jlf0103
  • jlf0103
  • 2015年07月02日 17:34
  • 179

Python特殊语法:filter、map、reduce、lambda、yield

Python内置了一些非常有趣但非常有用的函数,充分体现了Python的语言魅力! filter(function, sequence):对sequence中的item依次执行function(it...

惰性求值和yield-Python

惰性求值惰性求值(Lazy evaluation)是在需要时才进行求值的计算方式。表达式不在它被绑定到变量之后就立即求值,而是在该值被取用的时候求值。除可以得到性能的提升(更小的内存占用)外,惰性计算...

Python yield assert with 关键字

1. yield 关键字 包含了关键字"yield"的函数就不是普通的函数。当含有这个关键字的函数被调用的时候,这个函数在遇到yield的时候会停止运行,并且返回一个迭代器(iterator)。...

Python中的Iterables, Iterator, Generators, Yield

python中的iterables, iterator, generators, yield

python生成器:使用yield关键字定义迭代器

关于Python中的yield在介绍yield前有必要先说明下Python中的迭代器(iterator)和生成器(constructor)。一、迭代器(iterator)在Python中,for循环可...

新手学python(3):yield与序列化

1 Yield生成器        Yield是我在其他语言中没有见过的一个属性,算是python的一大特色,用好之后可以使代码更简洁。考虑一个简单的例子,文件的遍历。要遍历一个目录下的所有文件需要...

Python生成器:yield的使用

生成器概述通过列表生成式,我们可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝...
  • will130
  • will130
  • 2016年03月18日 11:11
  • 264

(译)Python关键字yield的解释(stackoverflow)

(译)Python关键字yield的解释(stackoverflow)          使用某度想了解Python的yield,结果~嗯~灰常失望。不得已,还是某哥给力啊,看到这么篇文章,看着简...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Python中幽灵般的yield
举报原因:
原因补充:

(最多只允许输入30个字)