我刚刚了解了回调的概念,因此决定尝试实现自己的回调。我的努力取得了丰硕的成果,我确实设法模拟了回调的功能。不幸的是,我注意到我的实现导致堆栈每个周期增加2个函数调用,如果代码运行足够长的时间,最终会导致堆栈溢出。
我想知道,如何实现此代码以防止堆栈在每个周期增长?还是这是该实施的必然产物,在这种情况下,如何避免此问题?
import time
import inspect
def doSomething(x):
return x + 0.00000001
def continue_processing(runningTotal,termination_condition,callback,callback_args,timeout=5):
startTime = time.time()
while (time.time() - startTime < timeout and not(termination_condition(runningTotal))):
runningTotal = doSomething(runningTotal)
print(f"Returning control to calling function, running total is {runningTotal}")
return callback(runningTotal,*callback_args)
def process(runningTotal,n,beginTime):
if(runningTotal < n):
print(f"Continue processing, running total is {runningTotal}\nTime elapsed {time.time() - beginTime}\nCurrent stack size: {len(inspect.stack())}")
continue_processing(runningTotal,lambda x: x>n,process,(n,beginTime))
if __name__ == '__main__':
beginTime = time.time()
try:
process(0,1,beginTime)
except KeyboardInterrupt:
print("Program interrupted!")
exit(0)
print(f"Completed in {time.time() - beginTime}"
答案 0 :(得分:0)
问题在于回调是递归的,它(间接)调用自身—这就是堆栈溢出的原因。下面是如何避免这种情况。请注意,我还更改了您的代码以符合PEP 8 - Style Guide for Python Code准则,以使其更具可读性。我强烈建议您阅读并遵循它,特别是如果您只是在学习语言。
import time
import inspect
def doSomething(x):
return x + 0.00000001
def continue_processing(runningTotal, termination_condition, timeout=5):
startTime = time.time()
while (time.time() - startTime < timeout
and not(termination_condition(runningTotal))):
runningTotal = doSomething(runningTotal)
print(f"Returning control to calling function, running total is "
f"{runningTotal}")
# Don't call back the callback
#return callback(runningTotal, *callback_args)
def process(runningTotal, n, beginTime):
while runningTotal < n:
print(f"Continue processing, running total is {runningTotal}\n"
f"Time elapsed {time.time() - beginTime}\n"
f"Current stack size: {len(inspect.stack())}")
continue_processing(runningTotal, lambda x: x>n)
if __name__ == '__main__':
beginTime = time.time()
try:
process(0, 1, beginTime)
except KeyboardInterrupt:
print("Program interrupted!")
exit(0)
print(f"Completed in {time.time() - beginTime}")