在循环中仅执行一次函数的高效方法
目前,我正在做一些像下面这样的事情,感觉有点繁琐:
run_once = 0
while 1:
if run_once == 0:
myFunction()
run_once = 1:
我在想,处理这些事情有没有更好的方法呢?
我想要的是让一个函数在需要的时候只执行一次。比如说,按下某个按钮的时候。这个应用是互动式的,有很多用户可以控制的开关。为了跟踪每个开关是否已经运行,我不得不为每个开关设置一个无用的变量,这样做感觉有点低效。
19 个回答
6
在循环之前运行这个函数。举个例子:
myFunction()
while True:
# all the other code being executed in your loop
这是一个显而易见的解决办法。如果事情比看起来的要复杂,解决方案可能会稍微复杂一些。
27
另一个选择是把你的函数的 func_code
设置为一个什么都不做的函数的代码对象。这一步应该在你的函数体的最后进行。
举个例子:
def run_once():
# Code for something you only want to execute once
run_once.func_code = (lambda:None).func_code
这里的 run_once.func_code = (lambda:None).func_code
是把你函数的可执行代码替换成了一个什么都不做的代码,所以之后每次调用 run_once()
都不会有任何效果。
这种方法比起在 被接受的答案 中提到的装饰器方式灵活性要差一些,但如果你只想让一个函数执行一次,这种方法可能会更简洁。
152
我会在这个函数上使用一个装饰器,来记录它运行了多少次。
def run_once(f):
def wrapper(*args, **kwargs):
if not wrapper.has_run:
wrapper.has_run = True
return f(*args, **kwargs)
wrapper.has_run = False
return wrapper
@run_once
def my_function(foo, bar):
return foo+bar
现在,my_function
这个函数只会运行一次。之后再调用它时,会返回 None
。如果你想让它返回其他东西,只需在 if
后面加一个 else
条件。从你的例子来看,它其实不需要返回任何东西。
如果你不能控制这个函数的创建,或者这个函数需要在其他地方正常使用,你也可以手动应用这个装饰器。
action = run_once(my_function)
while 1:
if predicate:
action()
这样就可以让 my_function
在其他地方继续使用。
最后,如果你只想让它运行一次或两次,那你可以直接这样做:
action = run_once(my_function)
action() # run once the first time
action.has_run = False
action() # run once the second time