Python等效的setInterval()?

zjm*_*126 37 python setinterval

Python有类似于JavaScript的功能setInterval()吗?

谢谢

sta*_*mat 29

这可能是您正在寻找的正确代码段:

import threading

def set_interval(func, sec):
    def func_wrapper():
        set_interval(func, sec)
        func()
    t = threading.Timer(sec, func_wrapper)
    t.start()
    return t
Run Code Online (Sandbox Code Playgroud)

  • 是否可以对此调用```t.cancel()```?它似乎忽略了它。 (3认同)
  • 这种方法仍然会相对较快地漂移,特别是如果等待时间低于一秒.有没有什么好的方法可以根据系统时间或RTC等类似接收信号(或调用函数)?从长远来看可能不会积累漂移的东西 (3认同)
  • 这是一些 Python3 代码来演示我的意思:http://pastebin.ubuntu.com/24304218/ (2认同)
  • 对于取消的可能性,没有阻塞和漂移,请看下面我的回答(/sf/ask/188792761/#48709380)。 (2认同)

dar*_*rix 9

只是保持简洁,我不知道为什么所有的答案都让事情变得如此复杂:

import threading

def setInterval(func,time):
    e = threading.Event()
    while not e.wait(time):
        func()

def foo():
    print "hello"

# using
setInterval(foo,5)

# output:
hello
hello
.
.
.
Run Code Online (Sandbox Code Playgroud)

编辑:此代码是非阻塞的

import threading

class ThreadJob(threading.Thread):
    def __init__(self,callback,event,interval):
        '''runs the callback function after interval seconds

        :param callback:  callback function to invoke
        :param event: external event for controlling the update operation
        :param interval: time in seconds after which are required to fire the callback
        :type callback: function
        :type interval: int
        '''
        self.callback = callback
        self.event = event
        self.interval = interval
        super(ThreadJob,self).__init__()

    def run(self):
        while not self.event.wait(self.interval):
            self.callback()



event = threading.Event()

def foo():
    print "hello"

k = ThreadJob(foo,event,2)
k.start()

print "It is non-blocking"
Run Code Online (Sandbox Code Playgroud)

  • 这个setInterval是阻塞的,并且setInterval(foo,5)之后的代码不会调用 (2认同)

doo*_*oom 9

这是一个可以启动和停止的版本.它没有阻止.没有故障,因为没有添加执行时间错误(对于长时间执行很重要,例如音频间隔非常短)

import time, threading

StartTime=time.time()

def action() :
    print('action ! -> time : {:.1f}s'.format(time.time()-StartTime))


class setInterval :
    def __init__(self,interval,action) :
        self.interval=interval
        self.action=action
        self.stopEvent=threading.Event()
        thread=threading.Thread(target=self.__setInterval)
        thread.start()

    def __setInterval(self) :
        nextTime=time.time()+self.interval
        while not self.stopEvent.wait(nextTime-time.time()) :
            nextTime+=self.interval
            self.action()

    def cancel(self) :
        self.stopEvent.set()

# start action every 0.6s
inter=setInterval(0.6,action)
print('just after setInterval -> time : {:.1f}s'.format(time.time()-StartTime))

# will stop interval in 5s
t=threading.Timer(5,inter.cancel)
t.start()
Run Code Online (Sandbox Code Playgroud)

输出是:

just after setInterval -> time : 0.0s
action ! -> time : 0.6s
action ! -> time : 1.2s
action ! -> time : 1.8s
action ! -> time : 2.4s
action ! -> time : 3.0s
action ! -> time : 3.6s
action ! -> time : 4.2s
action ! -> time : 4.8s
Run Code Online (Sandbox Code Playgroud)

  • 目前不能很好地处理 sigint 和 sigterm,一个想法是改进这一点,即导入信号并在两者上设置一个处理程序,在 main 中设置 while True 以无限地运行它,以侦听每当 sigint 或 sigterm 被触发时引发的自定义异常 (2认同)
  • @abe 只是创建多个 setInterval 对象 `inter1=setInterval(0.6,action1)` `inter2=setInterval(2,action2)` (2认同)

Eli*_*sky 6

sched模块为常规Python代码提供了这些功能.但是,正如其文档所示,如果您的代码是多线程的,那么使用threading.Timer该类可能更有意义.


vis*_*sum 6

我想这就是你所追求的:

#timertest.py
import sched, time
def dostuff():
  print "stuff is being done!"
  s.enter(3, 1, dostuff, ())

s = sched.scheduler(time.time, time.sleep)
s.enter(3, 1, dostuff, ())
s.run()
Run Code Online (Sandbox Code Playgroud)

如果您在重复方法的末尾添加另一个条目到调度程序,它就会继续进行。


Ste*_*jer 6

改变Nailxx的答案,你就得到了答案!

from threading import Timer

def hello():
    print "hello, world"
    Timer(30.0, hello).start()

Timer(30.0, hello).start() # after 30 seconds, "hello, world" will be printed
Run Code Online (Sandbox Code Playgroud)


Ala*_*iel 6

我使用sched创建setInterval函数要点

import functools
import sched, time

s = sched.scheduler(time.time, time.sleep)

def setInterval(sec):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*argv, **kw):
            setInterval(sec)(func)
            func(*argv, **kw)
        s.enter(sec, 1, wrapper, ())
        return wrapper
    s.run()
    return decorator


@setInterval(sec=3)
def testInterval():
  print ("test Interval ")

testInterval()
Run Code Online (Sandbox Code Playgroud)