生成器

  调用生成器函数,不会执行生成器函数中的代码,而是返回一个对象,  这个对象是生成器(可用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. ORA-00600 3020 ORA-10567案例

    PlateSpin克隆复制出的Oracle数据库服务器,往往启动数据库实例都会遇到一些杂七杂八的问题.今天测试DR环境时又遇到了一个特殊场景,在此之前,我已经遇到了下面两起案例: ORA-00600: ...

  2. webform(八)——LinQ简单增、删、改、查

    一.简单介绍 1.LinQ to Sql类(NET Language Integrated Query (LINQ) ) LINQ定义了大约40个查询操作符,如select.from.in.where ...

  3. 2.快速部署MySQL主从复制

      1.快速部署MySQL主从复制 [root@mysql ~]# mysql -uroot -p123456 -S /data/3307/mysql.sock -e "show slave ...

  4. IIS 启用CORS ,IISExpress 通过IP 访问

      在IIS 10中启用CORS: <system.webServer> <handlers> <remove name="OPTIONSVerbHandler ...

  5. Azure上的几个坑

    此文用于记录在使用Azure中国版时遇到的一些“坑”. 1.虚拟机备份/还原 在某些场景中,使用备份/还原功能来创建(克隆)虚拟机比使用capture的image要方便很多.虚拟机备份后,执行还原操作 ...

  6. input输入框的光标

    上午的时候,以前一起配合Java后端的哥们问了个input光标的问题. 需求是这样:只能输入数字的input(一开始以为是输入金额这些的,后来才晓得是用来填写手机号) 他采用是直接百度来的如下方法: ...

  7. git的学习

    学习怎么使用git这个分布式版本控制系统 学习资源 廖雪峰的git教程 Git的官方文档 Git命令列表 Git参考手册 中文 https://www.dropbox.com/s/sp2eupl8tp ...

  8. python 高级之面向对象初级

    python 高级之面向对象初级 本节内容 类的创建 类的构造方法 面向对象之封装 面向对象之继承 面向对象之多态 面向对象之成员 property 1.类的创建 面向对象:对函数进行分类和封装,让开 ...

  9. 什么时候用IntentService

    IntentService是继承自Service类的,在执行耗时操作时,其实,只需要在service中的onStartCommand(主线程)新启一个线程即可,那IntentService什么时候用来 ...

  10. 已知空间三个点,解算外接圆圆心坐标,C++编程实现

    struct PT3 { double x, y, z; }; int solveCenterPointOfCircle(std::vector<PT3> pt, double cente ...