Python范围/对象生命

时间:2015-03-09 03:42:15

标签: python

在这段代码的情况下,是否存储了k的对象,每次迭代都会被创建并删除?我认为它是,所以我通常在循环上面声​​明任何这样的变量。

while (1):
    k = randint(0,10)

4 个答案:

答案 0 :(得分:2)

是的,每次迭代都会创建一个新对象。至于删除,它是特定于实现的。例如,CPython使用引用计数,当它到达循环体的末尾时将删除k。在其他实现中,这些对象可以由垃圾收集器批量清除。见docs

  

永远不会明确销毁对象;然而,当它们变得无法到达时,它们可能被垃圾收集。允许实现推迟垃圾收集或完全省略它 - 实现垃圾收集的实现质量问题,只要没有收集到仍然可以访问的对象。

     

CPython实现细节:CPython目前使用引用计数方案和(可选)延迟检测循环链接垃圾,一旦它们无法访问就收集大多数对象,但不保证收集包含循环引用的垃圾。有关控制循环垃圾收集的信息,请参阅gc模块的文档。其他实现的行为不同,CPython可能会改变。当对象无法访问时,不要依赖于对象的立即终结(例如:总是关闭文件)。

答案 1 :(得分:1)

您可以查看id

>>> while True:
...     k = randint(1, 100)
...     print id(k)
...     time.sleep(1)
... 
140348572606072
140348572604112
140348572604600
140348572604912
^C
>>> 

这表明每个循环都会创建k

答案 2 :(得分:1)

正在创建的对象和丢弃每次迭代都是int,并且该过程不会受到循环前命名k的影响。我还认为对象/名称k在第一次迭代时是创建,然后在后续迭代中重新分配 - 在迭代期间不会被丢弃。

Python has names not variables

Facts and myths about Python names and values

答案 3 :(得分:0)

是的,如前所述,在每个循环上实例化一个新变量。但是,问题的根源是:

  

我认为是,所以我通常会声明任何这样的变量   在循环之上。

我只想指出,这种预初始化对时序没有影响。事实上,它会稍微慢一些,因为它必须在覆盖变量之前预先分配变量。

%%timeit
k = 0
for k in range(1000):
    k = randint(0, 10)

1000 loops, best of 3: 1.26 ms per loop

%%timeit
for k in range(1000):
    k = randint(0, 10)

1000 loops, best of 3: 1.26 ms per loop