Страницы

Поиск по вопросам

воскресенье, 29 марта 2020 г.

Ввод клавиатуры с тайм-аутом в Python. Как сделать чтобы программа не ждала вечно?

#python_3x #input #timeout


Программа запускается, и должна по умолчанию ждать 100 секунд ответа пользователя,
но ждёт вечно, пока не будет ввода. Как сделать чтобы программа ждала только 100 секунд?

Например, в программе ниже, если пользователь ввел 1, то программа выполняет сейчас
функцию, иначе пользователь ничего не ввел, будет ждать 10 часов и после этого выполнит
функцию для работы. Как для консоли написать программу, что работало примерно так:

work():
    print('это работает сейчас')



import time
print ('выполняем программу через 10 часов или сразу? 1 - сразу, *- через 10 часов(ничего
не введено)')
s = input('')

if s ==1:
    work()
else:
    time.sleep('36000')
    work()

    


Ответы

Ответ 1



Я создал для этого класс-обёртку, используя threading: from threading import Thread class Inp: inp = None def __init__(self): t = Thread(target=self.get_input) t.daemon = True t.start() t.join(timeout=100) def get_input(self): self.inp = input() def get(self): return self.inp inp = Inp().get() print(f'Вы ввели {inp}' if inp else f'Вы ничего не ввели!') Но данный код несовершенен, ввод получается "одноразовым". Мы можем продолжить программу, но если пользователь так ничего и не ввёл, то консоль всё ещё продолжит ждать его ввода. В Вашем случае - это не проблема, но решение неуниверсально.

Ответ 2



https://stackoverflow.com/questions/15528939/python-3-timed-input/15533404#15533404 from threading import Timer def work(): print('это работает сейчас') timeout = 36000 t = Timer(timeout, work) # Заводим таймер с обратным отсчетом 10 часов, который по тайм ауту выполнит функцию work t.start() # Запускаем таймер print ('Выполняем программу через 10 часов или сразу? 1 - сразу, *- через 10 часов (ничего не введено)') s = input() if s == "1": # Если пользователь ввёл "1", то отменяем отсчёт таймера и запускаем функцию сразу t.cancel() work() Стоит учитывать, что если 10 часов пройдёт, функция сработает, а потом пользователь введёт "1", то функция сработает ещё раз.

Ответ 3



В питоне есть библиотека для этих целей timeout_decorator С её использованием, ваша задача решается так import time from timeout_decorator import timeout, TimeoutError # decorator for setting timeout on function execution # seconds - how musch seconds to wait # default - value that will be returned on timeout def set_timeout(seconds, default=None): def _decorator(function): function = timeout(seconds)(function) def _wrapper(*args, **kwargs): try: return function(*args, **kwargs) except TimeoutError: return default return _wrapper return _decorator # waits for function execution # function - function with timeout # seconds - how musch seconds to wait # default - value that will be returned on timeout def wait_for(function, seconds, default=None): return set_timeout(seconds, default)(function) def work(): print('это работает сейчас') wait_input = wait_for(input, 100) text = wait_input() if text == '1': work() elif text is None: print('timeout') time.sleep(36000) work() В итоге таймаут можно выставить для любых существующих функций с помощью wait_for (создав новую функцию, но с таймаутом) wait_input = wait_for(input, 100) Либо для своей функции с помощью декоратора set_timeout @set_timeout(100) def wait_input(): # some more code return input() А также есть возможность задать возвращаемое значение по умолчанию, которое вернётся, если пользователь ничего не ввёл wait_input = wait_for(input, 100, default='sleep') text = wait_input() if text == '1': work() elif text == 'sleep': time.sleep(36000) work()

Ответ 4



@nomnoms12, я дополнила код и вот что получилось: import time from threading import Thread def work(): print('работает') class Inp: inp = None def __init__(self): t = Thread(target=self.get_input) t.daemon = True t.start() t.join(timeout=5) def get_input(self): self.inp = input() def get(self): return self.inp print('Введите что-нибудь и выполниться сейчас, иначе выполниться через 1 час...') inp = Inp().get() if inp: print(f'Вы ввели {inp}') work() else: print(f'Вы ничего не ввели! Выполниться через 1 ЧАС') time.sleep(3600) work()

Комментариев нет:

Отправить комментарий