2016-02-13 90 views
3

假設你正在發射火箭。當你上升時,你需要根據給定的表格來修正角度。但是,在某些情況下,您需要執行一次性操作(例如,釋放助推器,如果它們是空的,或者拋棄某個高度的整流罩)。實現Python`when`構造的最佳方式是什麼?

我現在正在做的是:

fairing_jettisoned = False 
while apogee < TARGET_APOGEE: 
    aim_rocket(speed, altitude, apogee) 
    if not fairing_jettisoned and altitude > FAIRING_ALT: 
     jettison_fairing() 
     fairing_jettisoned = True 

,因爲你必須來回跳轉這變得更復雜的程序非常繁瑣。

其他語言有when聲明(when altitude > FAIRING_ALT:),但在Python中不存在。

我試圖實現它的一種方法是類。這是哈克,但它似乎運作良好:

class when(object): 
    calls = {} 
    def __init__(self, expr, func, *args, runs_left=1, **kwargs): 
     _, fname, line, *_ = inspect.stack()[1] 
     stored_instance = when.calls.get((fname, line), self) 
     if stored_instance == self: 
      self.func = func 
      self.args = args 
      self.kwargs = kwargs 
      self.runs_left = runs_left 
      when.calls[(fname, line)] = self 
     self = stored_instance 
     self.expr = expr 
     if self.runs_left and self.expr: 
      self.runs_left -= 1 
      return self.func(*self.args, **self.kwargs 

這可以像這樣運行:

while apogee < TARGET_APOGEE: 
    aim_rocket(speed, altitude, apogee) 
    when(altitude > FAIRING_ALT, jettison_fairing) 

歸根結底,我想是有這種語法:

while apogee < TARGET_APOGEE: 
    aim_rocket(speed, altitude, apogee) 
    when(altitude > FAIRING_ALT, runs_left=3): 
     # Do a bunch of things; no need for a lambda or function. 
     jettison_fairing() 

我也嘗試過使用__enter____exit__來實現它,但是我找不到一個方法來跳到__exit__,如果它已經運行了。異步/等待可能會出現這種情況嗎?或者對於完全不同的東西呢?

+0

這似乎有點不必要,爲什麼不只是使用布爾值,這是在運行if語句時發生改變的,這是if語句的條件? –

+1

這就是我現在要做的。無論是布爾還是減量計數器。但是在代碼中上下移動會變得非常乏味,所以我想知道是否有更好的方法來實現它。 –

+0

那麼如果你現在正在使用這個代碼正在運行,那麼它似乎是一個很好的解決方案。至於將它作爲關鍵字實現,你將不得不編寫自己的Python版本(通過對CPython進行更改),我相信這絕對是不值得的。 –

回答

1

你可以嘗試使用線程,如設立了一句:

from threading import Thread 
import time, random 

def when(condition, action) -> Thread: 
    def threadtask(): 
     while not condition(): 
      time.sleep(0.5) 
     action() 
    t = Thread(target = threadtask) 
    t.start() 
    return t 

altitude = 1 
def jettison_fairing(): 
    print("Jettison the fairing!") 
when(lambda: altitude > 500, jettison_fairing) 
while altitude < 1000: 
    time.sleep(1) 
    altitude += random.randint(0,300) 
    print("Altitude is now ",altitude) 

# Output: 

##Altitude is now 173 
##Altitude is now 290 
##Altitude is now 370 
##Altitude is now 395 
##Altitude is now 464 
##Altitude is now 564 
##Jettison the fairing! 
##Altitude is now 736 
##Altitude is now 762 
##Altitude is now 1057 

獎勵積分,你可以寫一個裝飾,做那個。

但是,你所描述的是編程real-time systems所面臨的一些問題。沒有簡單的「時間」結構可以解決您的問題。 「何時」對你意味着什麼 - 例如,程序檢查高度的頻率如何?如果你的程序同時等待五十個不同的「時間」條件,那麼這些優先級中的哪一個更高?如果兩個「when」條件同時發生,會發生什麼情況?一組代碼告訴計算機拋棄整流罩,另一套則假定它仍然存在?

相關問題