假设我有一个函数可以启动Timer
来调用其他方法foo
:
def set_a_timer():
my_timer = threading.Timer(1200, foo)
my_timer.start()
...
return None
现在,此函数将在定时器完成之前返回,并且可能直到1200秒结束后才在我的程序中再次调用。程序将一直保持运行状态。
我知道,垃圾回收通常会清除范围外的变量。这意味着我将无法再在程序中访问my_timer
。很好-我需要的是在1200秒内执行它。但是它会在这1200秒后仍然执行foo
,还是会在有机会之前被垃圾收集器清理掉?
答案 0 :(得分:1)
简单的答案是:计时器仍将运行。
长答案是您在此处混淆变量和值。变量超出范围,但这对价值没有任何作用。 (与del
相同;它只是删除变量,而不是值。)
仅当最后一个对值的引用消失时,该值才变为垃圾。 (在CPython中,如果该值不在参考周期中,则意味着它会立即被销毁;在大多数其他实现中,只要GC注意到,它就会在稍后销毁。)
Timer
类是Thread
的子类。线程通过在后台线程中调用run
方法来工作。该方法的堆栈框架引用了它所需的任何内容,例如函数对象本身,以及所有局部变量,就像每个函数一样,因此这些值在该方法完成之前不会变成垃圾。这些本地变量之一是self
,因此Timer
对象本身仍被引用,因此不会造成垃圾。
(如果您查看来自文档的Timer
的源代码,您可以看到它的run
方法所做的基本上就是在Event
上等待1200秒,然后调用您的foo
函数。)
如果您想查看Timer
对象何时被销毁,可以对其进行子类化,并添加一个__del__
方法来打印一条消息(或者在该点上甚至打印整个堆栈)。