Python生成器

栏目: Python · 发布时间: 6年前

内容简介:Python生成器

目录

生成器函数是包含yield语句的函数。在生成器函数中,不能包含带参的return语句。

调用生成器函数,会返回一个生成器对象。

第一次启动生成器的时候,需要使用None作为参数调用生成器的send()方法,或者调用生成器的next()方法(next()等价于send(None))。生成器会从头开始执行,一直到:

  • 遇到yield ,yield的value会被当作send()或next()的返回值,控制权重新交给调用方
  • 或者 生成器执行结束 ,此时,send()或next()方法会抛出StopIteration异常

之后,可以使用send(<value>)或next()重新启动生成器,send的参数会作为上个yield语句的返回值,然后生成器会从上次yield的位置,继续执行,一直到:

  • 再次遇到yield ,yield的value会作为send()或next()的返回值,send的参数会作为yield的返回值,控制权重新交回给调用方
  • 或者 生成器执行结束 ,此时,send()或next()方法会抛出StopIteration异常

也可以通过生成器对象的throw(<exc_value>)方法,向生成器内部传递异常。

下面是一个用生成器,模拟生产者-消费者的例子:

[root@iZj6chejzrsqpclb7miryaZ ~]# cat test.py 
import time

class MainLoop:
    def __init__(self):
        self._gens = []
        self._is_stop = False

    def add_gen(self, gen_factory):
        if self._is_stop:
            return
        self._gens.append(gen_factory(self))

    def delete_gen(self, gen):
        while self._gens.find(gen) != -1:
            self._gens.remove(gen)

    def _run(self):
        cursor = 0
        while cursor < len(self._gens):
            try:
                self._gens[cursor].next()
            except Exception as ex:
                self._gens.pop(cursor)
                cursor = cursor - 1
                if not isinstance(ex, StopIteration):
                    print ex
            finally:
                cursor = cursor + 1

    def start(self):
        while not self._is_stop:
            self._run()
            if not self._gens:
                time.sleep(0.001)
        while self._gens:
            self._run()

    def stop(self):
        self._is_stop = True

current_count = 0
will_stop = False
batch_count = 10
max_count = 100


def producer(loop):
    global current_count, max_count, batch_count, will_stop
    produced_count = 0

    while produced_count < max_count:
        while current_count >= max_count / 2:
            print "[producer] threshold is reached..."
            yield

        print "[producer] begin producing"
        start_time = time.time()
        now = start_time
        while now - start_time < 0.2:
            yield
            now = time.time()

        current_count = current_count + batch_count
        produced_count = produced_count + batch_count
        print "[producer] produced %d/%d" % (produced_count, max_count)
        yield
    print "[producer] stop"
    will_stop = True
    loop.stop()

def consumer(loop):
    global current_count, will_stop
    consumed_count = 0

    while current_count > 0 or not will_stop:
        while current_count <= 0:
            print "[consumer] no goods, sleep 0.1"

            start_time = time.time()
            now = start_time
            while now - start_time < 1:
                yield
                now = time.time()

        current_count = current_count - 1
        consumed_count = consumed_count + 1
        print "[consumer] consumed %d/%d" % (consumed_count, max_count)
        yield
    print "[consumer] stop"

loop = MainLoop()
loop.add_gen(producer)
loop.add_gen(consumer)
loop.start()

[root@iZj6chejzrsqpclb7miryaZ ~]# python test.py 
[producer] begin producing
[consumer] no goods, sleep 0.1
[producer] produced 10/100
[producer] begin producing
[producer] produced 20/100
[producer] begin producing
[producer] produced 30/100
[producer] begin producing
[producer] produced 40/100
[producer] begin producing
[consumer] consumed 1/100
[consumer] consumed 2/100
[consumer] consumed 3/100
[consumer] consumed 4/100
[consumer] consumed 5/100
[consumer] consumed 6/100
[consumer] consumed 7/100
[consumer] consumed 8/100
[consumer] consumed 9/100
[consumer] consumed 10/100
[consumer] consumed 11/100
[producer] produced 50/100
[consumer] consumed 12/100
[producer] begin producing
[consumer] consumed 13/100
[consumer] consumed 14/100
[consumer] consumed 15/100
[consumer] consumed 16/100
[consumer] consumed 17/100
[consumer] consumed 18/100
[consumer] consumed 19/100
[consumer] consumed 20/100
[consumer] consumed 21/100
[consumer] consumed 22/100
[consumer] consumed 23/100
[consumer] consumed 24/100
[consumer] consumed 25/100
[consumer] consumed 26/100
[consumer] consumed 27/100
[consumer] consumed 28/100
[consumer] consumed 29/100
[consumer] consumed 30/100
[consumer] consumed 31/100
[consumer] consumed 32/100
[consumer] consumed 33/100
[consumer] consumed 34/100
[consumer] consumed 35/100
[consumer] consumed 36/100
[consumer] consumed 37/100
[consumer] consumed 38/100
[consumer] consumed 39/100
[consumer] consumed 40/100
[consumer] consumed 41/100
[consumer] consumed 42/100
[consumer] consumed 43/100
[consumer] consumed 44/100
[consumer] consumed 45/100
[consumer] consumed 46/100
[consumer] consumed 47/100
[consumer] consumed 48/100
[consumer] consumed 49/100
[consumer] consumed 50/100
[consumer] no goods, sleep 0.1
[producer] produced 60/100
[producer] begin producing
[producer] produced 70/100
[producer] begin producing
[producer] produced 80/100
[producer] begin producing
[producer] produced 90/100
[producer] begin producing
[producer] produced 100/100
[producer] stop
[consumer] consumed 51/100
[consumer] consumed 52/100
[consumer] consumed 53/100
[consumer] consumed 54/100
[consumer] consumed 55/100
[consumer] consumed 56/100
[consumer] consumed 57/100
[consumer] consumed 58/100
[consumer] consumed 59/100
[consumer] consumed 60/100
[consumer] consumed 61/100
[consumer] consumed 62/100
[consumer] consumed 63/100
[consumer] consumed 64/100
[consumer] consumed 65/100
[consumer] consumed 66/100
[consumer] consumed 67/100
[consumer] consumed 68/100
[consumer] consumed 69/100
[consumer] consumed 70/100
[consumer] consumed 71/100
[consumer] consumed 72/100
[consumer] consumed 73/100
[consumer] consumed 74/100
[consumer] consumed 75/100
[consumer] consumed 76/100
[consumer] consumed 77/100
[consumer] consumed 78/100
[consumer] consumed 79/100
[consumer] consumed 80/100
[consumer] consumed 81/100
[consumer] consumed 82/100
[consumer] consumed 83/100
[consumer] consumed 84/100
[consumer] consumed 85/100
[consumer] consumed 86/100
[consumer] consumed 87/100
[consumer] consumed 88/100
[consumer] consumed 89/100
[consumer] consumed 90/100
[consumer] consumed 91/100
[consumer] consumed 92/100
[consumer] consumed 93/100
[consumer] consumed 94/100
[consumer] consumed 95/100
[consumer] consumed 96/100
[consumer] consumed 97/100
[consumer] consumed 98/100
[consumer] consumed 99/100
[consumer] consumed 100/100
[consumer] stop

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

沸腾十五年

沸腾十五年

林军 / 中信出版社 / 2009-7 / 59.00

覆雨翻云的中国网事; 荡气回肠的产业传奇;虚拟世界的真实讲述;万象网络的还原走笔。 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本书记录了一群在中国创造属于自己历史的人和他们的故事,他们是中国互联网自1995年兴起的波澜壮阔中的弄潮儿和财富新贵的代表:马化腾、丁磊、张朝阳、马云、陈天桥、李彦宏、史玉柱、田溯宁、张树新、王志东、王峻涛、雷军、......一起来看看 《沸腾十五年》 这本书的介绍吧!

随机密码生成器
随机密码生成器

多种字符组合密码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器