在Python中聚合和推迟函数执行

时间:2016-07-02 18:26:06

标签: python

我在python中拥有自己的函数,偶尔会被其他一些代码每秒多次调用。我的功能如下:

def doIt(id):
    doSomething(id)

因此,doSomething()与doIt()的调用次数相同,这会导致麻烦。如何在最后一次调用doIt(id)后5秒钟聚合doIt(id)的调用并调用doSomething(id)? id参数是可变的,调用doIt(123)应该对doIt(789)

没有影响

1 个答案:

答案 0 :(得分:0)

嗯。如果我正确地阅读此问题,则问题是有人可以在五秒钟内多次拨打doIt(10),但您只需要每五秒钟调用doSomething(10)一次。< / p>

在这种情况下,您可以相对容易地在没有线程的情况下执行此操作doIt()可以记住上次使用某些参数调用doSomething()的时间,并且只有在它不是特别近期时再次调用它。

import timeit

doSomething_calls = {}

def doIt(id):
    now = timeit.default_timer()  # wallclock time in seconds
    if id in doSomething_calls:
        if now - doSomething_calls[id] > 5:  # If the last real call was more than 5 seconds ago
            doSomething(id)  # Do a new call
            doSomething_calls[id] = now  # And update the time we last did a real call
    else:
        doSomething(id)
        doSomething_calls[id] = now

明智地使用{}.get()可以大大减少这个功能,但我会将其作为练习留给你。如果没有人立刻向你抛出一切,那就很难学会了。 :)

或者,如果您希望拨打doSomething(x)的电话等到5小时内没有拨打doIt(x),您就需要线程或子进程以避免锁定你的程序在等待的时候。以下是您的表现方式:

import threading
import time
import timeit

doIt_calls = {}

def doIt(id):
    doIt_calls[id] = timeit.default_timer()

def doSomethingThread():
    to_delete = []
    while alive:
        now = timeit.default_timer()
        for id, wallclock_time in doIt_calls.items():
            if now - wallclock_time > 5:  # If the last time `doIt(id)` was called was longer than 5s ago
                doSomething(id)  # Enact the `doSomething()` call
                to_delete.append(id)  # Remove the scheduled call from the dictionary so we don't immediately call it again next loop.
        for id in to_delete:
            del doIt_calls[id]
        time.sleep(0.1)

alive = True  # set this False after the end of your program to kill the thread

thread = threading.Thread(target=doSomethingThread)
thread.start()

# Rest of your program

alive = False  # Tell the thread to die after it's done with the current loop