这是一个简单的有界生成器。
def bounded_naturals(limit):
num = 1
while num <= limit:
yield num
num += 1
Run Code Online (Sandbox Code Playgroud)
如果我写
bn_gen = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
bn_gen 将是预期的生成器对象。
但是如果我写
(a, b, c) = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
a、b和c分别为 1、2 和 3。这让我觉得很奇怪,因为代码中似乎没有任何东西要求生成器生成值。Python 规范中是否有需要这种解释的地方?
更惊人的是,如果我写
bn_gen = (a, b, c) = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
我得到了两个结果!bn_gen将是一个生成器对象,并且a,b和c将是 1、2 和 3。我应该如何理解发生了什么?
最后,如果我写
(a, b) = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
我得到: ValueError: too many values to unpack (expected 2).
如果编译器足够聪明来执行这些其他技巧,为什么在这种情况下只要求生成器提供所需的元素数量还不够聪明?
Python 文档中是否有一节解释了所有这些?
谢谢。
解包对任意可迭代对象进行操作,而不是序列,它通过迭代来实现。当你做
(a, b, c) = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
你问的Python遍历bounded_naturals(3)和结果分配到a,b和c。
一个多重赋值像
bn_gen = (a, b, c) = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
由左到右(分配RHS每个分配目标的工作不从右到左像一些其他语言)。生成器首先分配给bn_gen,然后分配给(a, b, c)。请注意,拆包会耗尽生成器,因此迭代bn_gen不会给您任何结果。
当你做
(a, b) = bounded_naturals(3)
Run Code Online (Sandbox Code Playgroud)
失败与 Python 不聪明无关。Python 不会默默地丢弃额外的值,因为这只会隐藏错误。迭代必须提供与解包请求一样多的元素。
请记住,仅仅因为某些代码可以被赋予非错误含义,并不意味着它应该。
所有这些都记录在赋值语句文档中。