空生成器
在玩树结构的时候,我发现了一个有趣的现象:
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 个回答
5
我理解的是,在一个函数里面使用的 yield
关键字是在编译时就被识别的。这样一来,这个函数就不再像普通的函数那样工作。当你调用一个包含 yield
关键字的函数时,它会立即返回一个懒惰的生成器对象,这个对象会根据函数的定义按需生成变量。只有当你遍历这个生成器时,函数里的代码才会被执行。
更简洁的解释可以在 这里 找到。
所以当调用 descendants
时,由于函数里面有 yield
关键字,立刻返回了一个生成器对象。不过,因为 descendants
立即 return
了,所以这个生成器并没有产生任何值,但它绝对还是一个生成器。