Python3.4 yield 与 yield from

时间:2015-08-11 23:33:25   收藏:0   阅读:1363

yield 语法

这一篇日志主要是参考Python 3: Using “yield from” in Generators

上一篇博文介绍了yield的使用,现在在写一个例子:

    class Node:
        def __init__(self,value):
            self.left = []
            self.value = value
            self.right = []

        def node_iterate(self):
            for value in self.child_iterate(self.left):
                v = yield value
                print(‘left v is %s‘ % v)
            v = yield self.value
            for value in self.child_iterate(self.right):
                v = yield value
                print(‘right v is %s‘ %s)

        def child_iterate(self,nodes):
            for node in nodes:
                input_value = yield node.value
                print(‘input value is %s‘ % input_value)

        def main():
            root = Node(0)
            root.left = [Node(i) for i in [1,2,3]]
            root.right = [Node(i) for i in [4,5,6]]
            it = root.node_iterate()
            total = it.send(None)
            while True:
                try:
                    ans = it.send(total)
                    total += ans
                except StopIteration:
                    break
                else:
                    print(‘ans is %s‘ % ans)
            print(‘total is %s‘ % total)
    if __name__ == ‘__main__‘:
        main()  

运行上面的代码:

技术分享

发现函数child_iterate()中的print(‘input_value is %s‘ % input_value)中输出的一直是’input_value is None’。以为在执行到input_value = yield value时,方法直接被yield了,下次直接从下一句语句开始执行。

因此,如果想要利用input_value的值做运算的话,是不可以的。

但是在node_iterate()中可以利用v = yield value的值做运算。但是观察v的值,它等于root.send(total)中传入的total的值。而在while语句中的ans的值,才是想要的值——节点的值。

node_iterate()v的值不是需要的值,加上这一句显然是多余的。此时就可以用yield from语法了。修改node_iterate()中的代码:

    def node_iterate(self):
        yield from self.child_iterate(self.left)
        input_value = yield self.value
        yield from self.child_iterate(self.right)

保存后在运行代码,会发现child_iterate()中的input_value有值了:

技术分享

如果只想用yield,可以使用send()next()方法,来控制生成器的运行。

还可以继续修改代码:

    class Node:
        def __init__(self,value):
            self.left = []
            self.value = value
            self.right = []

        def process(self):
            v = yield self.value
            print(‘v is %s‘ % v)

        def child_iterate(self,nodes):
            for node in nodes:
                yield from node.process()

        def node_iterate(self):
            yield from self.child_iterate(self.left)
            self.process()
            yield from self.child_iterate(self.right)

        ······

代码是不是看起来干净多了?使用yield from可以写更少的代码。

自己对yieldyield from还不是很熟,等到很熟的时候,好好的终结一下吧,现在先用着在说。因为如果asyncioaiohttpaiomysql这三个库,代码不可能离开yield from

加油吧!

版权声明:本文为博主原创文章,未经博主允许不得转载。

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!