空发电机

时间:2014-04-10 03:09:15

标签: python generator

玩弄树木,我偶然发现了这种行为:

def descendants (self):
    return #or "pass" or "42"

显然会返回None

另一方面:

def descendants (self):
    return
    yield 42

返回一个不产生任何内容的生成器(实际上是叶节点所需的行为)。

有人可以向我解释一下这里发生了什么吗?

不应该yield 42无法访问代码吗?(我猜是一个函数是生成器还是"正常"函数的决定是在编译时间,根据它是否包含一个或多个yield语句,是否可以访问。但这只是一个黑暗的镜头。)


上下文如下:我有树,每个节点都是树或叶子。现在我想生成一个节点的所有后代:

class Leaf (Node):
    @property
    def descendants (self):
        return
        yield 42

class Tree (Node):
    @property
    def descendants (self):
        for child in self.children:
            yield child
            yield from child.descendants

1 个答案:

答案 0 :(得分:5)

据我了解,函数内的yield关键字在编译时被检测到。结果是该函数不再像普通函数那样运行。当调用带有yield关键字的函数时,函数IMMEDIATELY返回一个惰性生成器对象,该对象根据定义的函数根据需要生成变量。函数中的代码仅在迭代生成器时运行。

它更简洁地解释了here.

因此调用descendants,并且由于函数中存在yield关键字,因此会立即返回生成器对象。但是,由于descendants立即生成return,因此生成器不会产生任何值 - 但它绝对仍然是生成器。