在Python中聚合和延迟函数执行
我在python中有自己的函数,偶尔会被其他代码每秒多次调用。我的函数如下所示:在Python中聚合和延迟函数执行,python,Python,我在python中有自己的函数,偶尔会被其他代码每秒多次调用。我的函数如下所示: def doIt(id): doSomething(id) 因此,doSomething()的调用次数与doIt()的调用次数相同,这会造成麻烦。如何在最后一次调用doIt(id)5秒后聚合doIt(id)调用和doSomething(id)调用一次?id参数是可变的,调用doIt(123)应该对doIt(789)没有影响。如果我读对了,你的问题是有人可以在五秒钟内多次调用doIt(10),但你只希望每五
def doIt(id):
doSomething(id)
因此,doSomething()的调用次数与doIt()的调用次数相同,这会造成麻烦。如何在最后一次调用doIt(id)5秒后聚合doIt(id)调用和doSomething(id)调用一次?id参数是可变的,调用doIt(123)应该对doIt(789)没有影响。如果我读对了,你的问题是有人可以在五秒钟内多次调用doIt(10),但你只希望每五秒钟调用一次
doSomething(10)
在这种情况下,您可以相对轻松地在没有线程的情况下执行此操作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
听起来您需要一个线程和/或time.sleep此解决方案只有在永远调用doIt(id)时才有效。不幸的是,它被称为apx。20倍,只需2秒,在不久的将来,它将不再被调用。这就是为什么我需要doSomething(id)在最后一次调用doIt(id)5秒后只调用一次。我的解决方案最多每5秒调用一次
doSomething()
,这不是你想要的吗?您的意思是在最后一次调用doIt(x)
5秒后调用doSomething(x)
?在这种情况下,您将需要线程来避免锁定程序。如果是这种情况,请告诉我,我将编辑我的答案。是的,doSomething(x)应该在最后一次调用doIt(x)后5秒调用,必须更改为循环以在doIt_calls.items()中迭代
使其正常工作,但无论如何,我得到了RuntimeError:字典在迭代过程中改变了大小。这就是我从内存而不是交互式解释器编写字典的结果。再次编辑我的答案,这应该是最后一次了:D