来自函数

时间:2017-03-16 17:32:56

标签: python python-3.x generator

在玩发电机的过程中,我找到了有趣的东西。当我用yield关键字定义一个函数时,从它接收了一个生成器,我还删除了带有序列的变量,该变量被输入到函数中。并且* POOF!* - 发电机变空。这是我的步骤:

>>> def foo(list_):
...     for i in list_:
...             yield i*2
... 
>>> val = [1, 2, 3, 4]
>>> gen = foo(val)
>>> print(tuple(gen))
(2, 4, 6, 8)
>>> del val
>>> print(tuple(gen))
()
>>> 

它不应该是不可变的吗?或者,如果它实际上作为对象将其变量的所有值提供给它的函数,给出输出,为什么它没有因为没有链接序列而抛出异常?实际上,这个例子可以解释为我迭代一个空序列,这导致块for _ in []:永远不会启动。但是,我无法解释为什么这个不会抛出异常:

>>> def foo(list_):
...     for i in list_:
...             yield i*2
... 
>>> val = [1, 2, 3, 4]
>>> gen = foo(val)
>>> print(tuple(gen))
(2, 4, 6, 8)
>>> del foo
>>> print(tuple(gen))
()
>>> 

此处的生成器是否与dict.get()函数类似?我不明白这一点。

1 个答案:

答案 0 :(得分:4)

这与被删除的对象无关。相反,你已经耗尽了发电机;生成器只能迭代一次。如果需要再次迭代,请从生成器函数创建新的生成器。您在不删除引用的情况下看到相同的行为:

del foo

请注意,del valgen = foo(val); del foo, val仅删除对象的引用。如果存在对其的其他引用,则不会完全删除该函数或列表对象,例如从该函数创建的现有生成器。因此gen不会破坏foo对象,它仍然可以在没有valgen引用的情况下生成值,因为>>> gen = foo(val) >>> del foo, val >>> list(gen) # gen still references the list and code objects [2, 4, 6, 8] 本身仍然引用了什么它需要完成:

If(record does not exists in target table)
If(dbcal is not set)
Insert 
Else
Reject
Else if(record  exists in target table)
If(dbcal is not set)
Update
Else
Delete