在函数中取消计时器的问题(python)

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (215)

我有一个循环中不断运行的函数,检查它是否应该启动或取消在函数范围内定义的计时器。需要在函数内定义Timer,因为函数中也定义了回调。我能够很好地启动计时器,但是当它试图取消时,我得到一个错误'本地变量'计时器'在赋值之前被引用'。

我已经尝试在全局范围内定义计时器及其回调(这是不可取的),我得到另一个错误'线程只能启动一次'。

import threading
import random

def start():
    trigger = random.randint(0,1)
    def do_something():
        print(trigger)
    if trigger == 0:
        timer = threading.Timer(2,do_something)
        timer.start()
    else:
        timer.cancel() #: if trigger is 1, I want to cancel the timer
    threading.Timer(1,start).start() #: start() is in a loop and is constantly checking trigger's value

start()

我希望根据触发器的值启动或取消相同的计时器。计时器及其回调应该在函数内定义。

提问于
用户回答回答于

我从@quamrana和@smci那里学到了很多东西

import threading
import random

class Timer():
    pass
t = Timer()

def start():
    trigger = random.randint(0,1)
    def do_something():
        print(trigger)
    if trigger == 0:
        t.timer = threading.Timer(1,do_something)
        t.timer.start()
    else:
        if hasattr(t,'timer'):
            t.timer.cancel() 
    threading.Timer(1,start).start() 

start()

这似乎解决了这个问题,同时保持代码紧凑。

用户回答回答于

该程序显示了如何使用随机数来启动或停止计时器。

如果随机数0连续选择足够的次数,则计时器将启动并被允许继续计时,直到时间用完并且它调用其目标。

如果随机数选择1,则取消定时器并且不调用目标:

import threading
import random
import time

class Timing:
    def __init__(self):
        self.timer = None       # No timer at first
        self.something = None   # Nothing to print at first
        self.restart()

    def restart(self):
        self.run = threading.Timer(1.1, self.start)
        self.run.start()

    def cancel(self):
        if self.run is not None:
            self.run.cancel()
            self.run = None

    def start(self):
        trigger = random.randint(0, 1)
        self.do_start(trigger)

    def do_start(self, trigger):
        print('start', trigger)
        if trigger == 0:
            if self.timer is None:
                self.something = trigger
                self.timer = threading.Timer(2, self.do_something)
                self.timer.start()
        else:
            if self.timer is not None:
                self.timer.cancel()
                self.timer = None
                self.something=None
        self.restart()

    def do_something(self):
        print(self.something)

t = Timing()

print('sleeping...')
time.sleep(20)
t.cancel()
t.do_start(1)
t.cancel()
print('Done')

样本输出(ymmv因为它是随机的)

sleeping...
start 1
start 0
start 1
start 0
start 0
0
start 1
start 0
start 1
start 1
start 1
start 1
start 1
start 0
start 1
start 0
start 0
0
start 1
start 0
start 1
Done

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励