如何为不是函数的代码块设置超时 python3
How to set timeout for a block of code which is not a function python3
在Whosebug上找了好几个小时的解决方案,也没找到好的解决方案,给一段代码设置超时时间。有一些近似值可以为函数设置超时。不过,我想知道如何在没有功能的情况下设置超时。我们以下面的代码为例:
print("Doing different things")
for i in range(0,10)
# Doing some heavy stuff
print("Done. Continue with the following code")
那么,如果 for 循环在 x 秒后仍未完成,您将如何中断它?继续代码(可能保存一些 bool 变量以知道超时已到),尽管 for 循环没有正确完成。
您可以尝试以下方式:
import time
start = time.time()
for val in range(10):
# some heavy stuff
time.sleep(.5)
if time.time() - start > 3: # 3 is timeout in seconds
print('loop stopped at', val)
break # stop the loop, or sys.exit() to stop the script
else:
print('successfully completed')
我想这是一种可行的方法。实际超时大于3秒,取决于单步执行时间。
我认为在不使用函数的情况下有效地实现这一点是不可能的,看看这段代码..
import datetime as dt
print("Doing different things")
# store
time_out_after = dt.timedelta(seconds=60)
start_time = dt.datetime.now()
for i in range(10):
if dt.datetime.now() > time_started + time_out:
break
else:
# Doing some heavy stuff
print("Done. Continue with the following code")
问题:超时将在每个循环周期的开始检查,因此可能需要超过指定的超时时间才能中断循环,或者在最坏的情况下它可能不会中断循环因为它无法中断未完成 un 迭代的代码。
更新:
正如 op 重播的那样,他想要更有效的方法,这是一种正确的方法,但是使用函数。
import asyncio
async def test_func():
print('doing thing here , it will take long time')
await asyncio.sleep(3600) # this will emulate heaven task with actual Sleep for one hour
return 'yay!' # this will not executed as the timeout will occur early
async def main():
# Wait for at most 1 second
try:
result = await asyncio.wait_for(test_func(), timeout=1.0) # call your function with specific timeout
# do something with the result
except asyncio.TimeoutError:
# when time out happen program will break from the test function and execute code here
print('timeout!')
print('lets continue to do other things')
asyncio.run(main())
预期输出:
doing thing here , it will take long time
timeout!
lets continue to do other things
注:
现在超时将在您指定的时间后发生。在此示例代码中,一秒钟后。
您将替换此行:
await asyncio.sleep(3600)
使用您的实际任务代码。
尝试一下,让我知道您的想法。谢谢。
阅读 asyncio 文档:
link
更新 24/2/2019
正如 op 指出 asyncio.run 在 python 3.7 中引入并要求在 python 3.6
上提供替代方案
asyncio.run python 比 3.7 更早的替代方案:
替换
asyncio.run(main())
使用旧版本代码(我认为是 3.4 到 3.6)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
在Whosebug上找了好几个小时的解决方案,也没找到好的解决方案,给一段代码设置超时时间。有一些近似值可以为函数设置超时。不过,我想知道如何在没有功能的情况下设置超时。我们以下面的代码为例:
print("Doing different things")
for i in range(0,10)
# Doing some heavy stuff
print("Done. Continue with the following code")
那么,如果 for 循环在 x 秒后仍未完成,您将如何中断它?继续代码(可能保存一些 bool 变量以知道超时已到),尽管 for 循环没有正确完成。
您可以尝试以下方式:
import time
start = time.time()
for val in range(10):
# some heavy stuff
time.sleep(.5)
if time.time() - start > 3: # 3 is timeout in seconds
print('loop stopped at', val)
break # stop the loop, or sys.exit() to stop the script
else:
print('successfully completed')
我想这是一种可行的方法。实际超时大于3秒,取决于单步执行时间。
我认为在不使用函数的情况下有效地实现这一点是不可能的,看看这段代码..
import datetime as dt
print("Doing different things")
# store
time_out_after = dt.timedelta(seconds=60)
start_time = dt.datetime.now()
for i in range(10):
if dt.datetime.now() > time_started + time_out:
break
else:
# Doing some heavy stuff
print("Done. Continue with the following code")
问题:超时将在每个循环周期的开始检查,因此可能需要超过指定的超时时间才能中断循环,或者在最坏的情况下它可能不会中断循环因为它无法中断未完成 un 迭代的代码。
更新:
正如 op 重播的那样,他想要更有效的方法,这是一种正确的方法,但是使用函数。
import asyncio
async def test_func():
print('doing thing here , it will take long time')
await asyncio.sleep(3600) # this will emulate heaven task with actual Sleep for one hour
return 'yay!' # this will not executed as the timeout will occur early
async def main():
# Wait for at most 1 second
try:
result = await asyncio.wait_for(test_func(), timeout=1.0) # call your function with specific timeout
# do something with the result
except asyncio.TimeoutError:
# when time out happen program will break from the test function and execute code here
print('timeout!')
print('lets continue to do other things')
asyncio.run(main())
预期输出:
doing thing here , it will take long time
timeout!
lets continue to do other things
注:
现在超时将在您指定的时间后发生。在此示例代码中,一秒钟后。
您将替换此行:
await asyncio.sleep(3600)
使用您的实际任务代码。
尝试一下,让我知道您的想法。谢谢。
阅读 asyncio 文档: link
更新 24/2/2019
正如 op 指出 asyncio.run 在 python 3.7 中引入并要求在 python 3.6
上提供替代方案asyncio.run python 比 3.7 更早的替代方案:
替换
asyncio.run(main())
使用旧版本代码(我认为是 3.4 到 3.6)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()