生成器

  调用生成器函数,不会执行生成器函数中的代码,而是返回一个对象,  这个对象是生成器(可用type()函数判断这个对象类型),  如果要运行生成器函数中的代码, 需要调用 next()方法,  next()方法会在遇到 yield 语句的地方停止运行.

不停地调用生成器对象的 next()方法,即可获得一个序列。

  一般不需要直接调用 next()方法,而是使用 for 语句:

def countdown(n):
    print 'counting down from %d'%n
    while n>0:
        yield n
        n -= 1

for n in countdown(10):
    print n

a = sum(countdown(10))

  传递给 yield 的值,会通过next()方法返回。

  next()方法 当遇到yield时暂停函数的执行,并返回。当下一次再调用next()时恢复函数的执行. 可以通过打印信息来说明生成器的执行情况。

  生成器函数在每次暂停执行时,函数体内的所有变量都将被封存(freeze)在生成器中.

def countdown(n):
    print '---------1'
    while n > 0:
        print '---------2'
        yield n
        print '---------3'
        n -= 1
        print '---------4' 

调用生成器,并查看运行情况:

c = countdown(5)
c.next()
c.next()
c.next() 

  当生成器函数返回 , 或者 抛出 StopIteration 时, 生成器才运行完.   生成器函数除了返回None ,其它类型的返回值都是非法的.

  可以调用生成器的close方法来终止生成器的运行.  close()方法会触发 GeneratorExit异常,可在生成器函数中捕获,并做一些清理工作.

协程和yield 表达式

  在函数中,yield语句也可以作为 一个表达式出现在赋值符号的右边 , 如:

def receiver():
    print 'ready to receive'
    while True:
        n = (yield)
        print 'Got %s'%n

  当函数以这种方式使用 yield 时 , 这个函数称为 coroutine  ( 协程 ).  它对发送给他的值做出响应。

  一般函数只处理单个的输入参数集合, 而协程则是对一连串发送给它的输入参数进行处理。 协程是通过 yield 语句创建的。

  

  传递给send()的参数 ,会被 yield表达式返回。

装饰器

  装饰器是一个函数,其主要目的是封装另外一个函数或者类。

  

@trace
def square(x):
    return x*x

#上面的装饰器是以下代码的简写

def square(x):
    return x*x
square = trace(square) #square已经是另一个函数了.

  经过装饰器修饰过的函数,当实际调用时,调用的已经不是被修饰的函数,而是另一个新的函数。

  装饰器也能够接受参数:

@eventhandler('button')
def handle_button(msg):
    ....

#实际的调用过程为

temp = eventhandler('button')
handle_button = temp(handle_button)

修饰类的装饰器

  由于装饰器是一个函数,当它修饰类时,则这个函数需要返回类的对象。(对于修饰类的装饰器返回函数也是可以的,只是如果是返回函数,如果要访问对象的成员,则没法访问)

@foo
class Bar(object):
    def __init__(self,x):
        self.x = x

    def spam(self):
        statements

列表解析和生成器表达式

  生成器和列表解析基本功能是一样的,  一点微小的差别是 生成器表达式使用小括号, 而列表解析使用中括号.

  并且在列表解析中, python实际上是创建一个包含结果数据的列表;  在生成器表达式中, python创建的是一个生成器对象, 它知道如何根据需要来产生数据.

declarative programming

lambda 运算符

  表达式形式的匿名函数,可以通过 lambda 语句.  如:

lambda args : expression

  args 是逗号分隔的参数.   expression是设计到这些参数的表达式.  例如:

  a = lambda x, y : x + y
  r = a(2,3)              #r  == 5

  expression必须是一个有效的表达式, 多条语句和其他非表达式的语句, 例如 for , while 不能出现在 lambda 语句中.

  lambda 主要的用法是定义简短的回调函数.

Recursion 递归

  可以很轻易定义递归函数,例如:

def factorial(n):
    if n <= 1:
        return 1
    else:
        return n * factorial(n-1)

  但是需要注意递归的深度问题.   sys.getrecursionlimit() 函数返回递归的最大允许深度. (受限于主机的栈空间大小).    超过最大深度, 程序可能会抛出 RuntimeError 异常.

  

  

python 生成器等语法的更多相关文章

  1. python yield from 语法

    python yield from 语法 yield语法比较简单, 教程也很多 , yield from的中文讲解很少 , python官网是这样解释的 PEP 380 adds the yield ...

  2. [译]PEP 380--子生成器的语法

    导语: PEP(Python增强提案)几乎是 Python 社区中最重要的文档,它们提供了公告信息.指导流程.新功能的设计及使用说明等内容.对于学习者来说,PEP 是非常值得一读的第一手材料,学习中遇 ...

  3. 四. Python基础(4)--语法

    四. Python基础(4)--语法 1 ● 比较几种实现循环的代码 i = 1 sum = 0 while i <= 10: # 循环10-1+1=10次     sum += i     i ...

  4. Python 生成器总结

    生成器的概念: 生成器不会把结果保存在一个系列中,而是保存在生成器的状态,在每次进行迭代时返回一个值,直到遇到StopIteration异常结束 生成器是这样一个函数,它记住上一次返回时在函数体中的位 ...

  5. python生成器,函数,数组

    1.什么是生成器用一个比喻来形容,工厂中生产保龄球的流水线,机器每次只生产一个保龄球,下次继续生产下一个,直到停止(原料不足,停止供电等条件)为止.机器就是我们的生成器. 2.使用示例在python中 ...

  6. python语句和语法

    python语句和语法 python程序结构: 1.程序由模块构成. 2.模块包含语句. 3.语句包含表达式. 4.表达式建立并处理对象. python的语法实质上是有语句和表达式组成的.表达式处理对 ...

  7. python 生成器与迭代器(yield 用法)

    背景 首先,我不会解释这两个名词,我看过很多遍解释,可还是看不懂,还是直接看使用情景吧. 我们以佩波拉契数列为例,当我们不知道迭代器的情况下,我们写出来的代码可能是这样子的: '''这种方式计算fib ...

  8. 【python之路29】python生成器generator与迭代器

    一.python生成器 python生成器原理: 只要函数中存在yield,则函数就变为生成器函数 #!usr/bin/env python # -*- coding:utf-8 -*- def xr ...

  9. Generator - Python 生成器

    Generator, python 生成器, 先熟悉一下儿相关定义, generator function 生成器函数, 生成器函数是一个在定义体中存有 'yield' 关键字的函数. 当生成器函数被 ...

随机推荐

  1. 看看C# 6.0中那些语法糖都干了些什么(终结篇)

    终于写到终结篇了,整个人像在梦游一样,说完这一篇我得继续写我的js系列啦. 一:带索引的对象初始化器 还是按照江湖老规矩,先扒开看看到底是个什么玩意. 1 static void Main(strin ...

  2. 关于Oracle的疑问

    索引范围扫描(index range scan) select empno,ename from emp where empno > 1 order by empno 这种情况下不会使用索引范围 ...

  3. Oracle发送邮件,支持HTML,多收件人,多附件

    Oracle发邮件,权限问题 - 创建 ACL BEGIN DBMS_NETWORK_ACL_ADMIN.CREATE_ACL(acl => 'email_server_permissions. ...

  4. tomcat加密

    tomcat做虚拟主机的最好方法是复制,运行多个tomcat,避免tomcat挂掉,同时几个业务也挂掉 针对tomcat7,tomcat未实现 生成私钥证书文件: mkdir -p /usr/loca ...

  5. Python Socket 编程——聊天室示例程序

    上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...

  6. 初识redis数据类型

    初识redis数据类型 1.String(字符串) string是redis最基本的类型,一个key对应一个value. string类型是二进制安全的.意思是redis的string可以包含任何数据 ...

  7. 有理数的稠密性(The rational points are dense on the number axis.)

    每一个实数都能用有理数去逼近到任意精确的程度,这就是有理数的稠密性.The rational points are dense on the number axis.

  8. 用js实现动画效果核心方式

    为了做好导航菜单,有时候需要在菜单下拉的时候实现动画效果,所以这几天就研究了研究如何用js实现动画效果,实现动画核心要用到两个函数,一个是setTimeOut,另一个是setInterval. 下边我 ...

  9. Java NIO (转)

    Java NIO提供了与标准IO不同的IO工作方式: Channels and Buffers(通道和缓冲区):标准的IO基于字节流和字符流进行操作的,而NIO是基于通道(Channel)和缓冲区(B ...

  10. 负margin的移位参考线

    同早年~ 问题描述 在xx项目中,羊城通卡号的输入框处使用了xx库中的实现方式,即将提示文字标签<label>通过负margin移位到<input>框的下面.静态时展现良好,j ...