2016-02-13 60 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”条件同时发生,会发生什么情况?一组代码告诉计算机抛弃整流罩,另一套则假定它仍然存在?

相关问题