2016-07-02 31 views
-1

我在Python中有自己的函數,偶爾會被其他代碼每秒多次調用。我的功能看起來是這樣的:在Python中聚合和推遲函數執行

def doIt(id): 
    doSomething(id) 

因此DoSomething的()被調用相同的次數爲doIt方法(),並且是造成麻煩。如何在doIt(id)的最後一次調用後5秒鐘內彙總doIt(id)的呼叫並調用doSomething(id)? id參數是可變的,並且調用doIt(123)應該對doIt沒有影響(789)

+0

聽起來像是你想有一個線程和/或time.sleep –

回答

0

嗯。如果我正在閱讀這個權利,您的問題是有人可能會在五秒鐘內多次致電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)等待,直到沒有任何呼叫doIt(x) 5秒鐘,您將需要線程或子進程以避免在等待時鎖定程序。這裏是你會怎麼做:

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 
+0

該解決方案將工作只有doIt方法(ID)被永遠調用。不幸的是它被稱爲APX。 20x只需2秒,然後在不久的將來不再調用。這就是爲什麼我需要doSomething(id)在最後一次調用doIt(id) – igo

+0

後5秒纔會調用。我的解決方案最多每5秒調用一次doSomething(),這不是你想要的嗎? 你的意思是說'doSomething(x)'應該在_final_調用'doIt(x)'5秒後調用?在這種情況下,您將需要線程來避免鎖定程序。讓我知道如果是這樣,我會編輯我的答案。 –

+0

是的,doSomething(x)應該在最後一次調用doIt後調用5秒鐘(x) – igo