Как установить таймаут для блока кода, который не является функцией python3 - PullRequest
0 голосов
/ 14 февраля 2019

Потратив много часов на поиск решения в stackoverflow, я не нашел хорошего решения для установки таймаута для блока кода.Есть аппроксимации для установки времени ожидания для функции.Тем не менее, я хотел бы знать, как установить таймаут без функции.Давайте возьмем следующий код в качестве примера:

    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 не завершился должным образом.

Ответы [ 2 ]

0 голосов
/ 14 февраля 2019

Я думаю, что реализовать это эффективно без использования функций невозможно, посмотрите этот код ..

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")

проблема: время ожидания будет проверяться в начале каждого цикла цикла, поэтому может потребоваться больше, чемзаданный период ожидания для прерывания цикла, или в худшем случае он может не прерывать цикл, потому что он не может прерывать код, который никогда не завершает без итерации.


update:

как оп воспроизведен, что он хочет более эффективный способ, это правильный способ сделать это, но с использованием функций.

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: ссылка

обновление 24/2/2019

as op отметил, что asyncio.run введен в python 3.7 и запросил альтернативу для python 3.6

asyncio.run альтернатива для python старше 3.7:

replace

asyncio.run(main())

с этим кодом для более старой версии (я думаю, что от 3,4 до 3,6)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()
0 голосов
/ 14 февраля 2019

Вы можете попробовать следующий способ:

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 секунды и зависит от времени выполнения одного шага.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...