这是一个简单的有界生成器。
def bounded_naturals(limit):
num = 1
while num <= limit:
yield num
num += 1
如果我写
bn_gen = bounded_naturals(3)
bn_gen
将是预期的生成器对象。
但是如果我写
(a, b, c) = bounded_naturals(3)
a
、b
和 c
将分别为 1、2 和 3。这让我觉得很奇怪,因为代码中似乎没有任何内容要求生成器生成值。 Python 规范中是否有地方需要这种解释?
更引人注目的是,如果我写
bn_gen = (a, b, c) = bounded_naturals(3)
我得到了两个结果! bn_gen
将是一个生成器对象,a
、b
和 c
将是 1、2 和 3 . 我应该如何理解发生了什么?
最后,如果我写
(a, b) = bounded_naturals(3)
我得到:ValueError:要解压的值太多(预期为 2)。
如果编译器足够聪明,可以执行这些其他技巧,为什么在这种情况下它不能足够聪明地向生成器询问所需数量的元素?
Python 文档中是否有解释所有这些的部分?
谢谢。
最佳答案
解包操作任意可迭代对象,而不是序列,它通过迭代来实现。当你做的时候
(a, b, c) = bounded_naturals(3)
您要求 Python 迭代 bounded_naturals(3)
并将结果分配给 a
、b
和 c
.
像这样的多重赋值
bn_gen = (a, b, c) = bounded_naturals(3)
通过从左到右将 RHS 分配给每个分配目标来工作(不是像其他一些语言那样从右到左)。生成器首先被分配给 bn_gen
,然后分配给 (a, b, c)
。请注意,解包会耗尽生成器,因此遍历 bn_gen
不会给您任何结果。
当你做的时候
(a, b) = bounded_naturals(3)
失败与 Python 不聪明无关。 Python 不会默默地丢弃额外的值,因为那样只会隐藏错误。可迭代对象必须提供与解包请求一样多的元素。
请记住,仅仅因为某些代码可以被赋予非错误含义,并不意味着它应该。
所有这些都记录在 assignment statement docs 中.
关于python - 关于 "unpacking"生成器的 Python 规则是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66558665/