Найти - Пользователи
Полная версия: Прерывание скрипта и повторный запуск
Начало » Python для новичков » Прерывание скрипта и повторный запуск
1
robisho
Добрый день. Задача такая: при работе скрипта нужно его остановить, а затем продолжить выполнение с того же места остановки. Например, при парсинге или массовой отправки сообщений smtp. Т.е. структура, я думаю, будет одна: из списка берется url или email и обрабатывается в функции парсинга/smtp. Нужно при остановке скрипта дать функции парсинга/smtp завершиться и остановиться на выдаче очередного url/email, а при повторном запуске начать с точки останова. Подскажите, пожалуйста, как это можно осуществить? Интересуют все возможные теории/названия/библиотеки. Спасибо.
py.user.next
robisho
Подскажите, пожалуйста, как это можно осуществить?
Можно сделать по принципу, который есть у браузеров и программ для закачки. Когда она закачивает, она регистрирует все закачанные части. При её остановке остаются эти файлы, в которых записано то последнее, что закачалось. При новом запуске она ищет эти файлы, в которых записано, что там было до этого запуска, и по ним действует дальше, так же их меняя.

robisho
Нужно при остановке скрипта дать функции парсинга/smtp завершиться и остановиться на выдаче очередного url/email
При сигнале остановки программа должна доделать задачу и выйти из-за того, что был получен этот сигнал остановки. Ну, ты получаешь сигнал, устанавливаешь флажок, что был получен сигнал, а в конце цикла этот флажок проверяется.

Я такой закачник делал, я очень много накачал им в итоге. У него в текстовый файл можно было занести сотню ссылок и он помечал каждую (закачивалась она или не закачивалась), всегда можно было залезть в этот файл и пометить какую-нибудь закачанную ссылку, что она не закачана, и она тогда по новой качалась. При этом при закачке эти недокачанные файлы сохранялись под специальными именами на основе md5-хешей, чтобы они все были уникальными, а после закачки этих файлов, которая могла быть продолжена через несколько дней, через неделю, через месяц, эти хеши срезались просто и в конечных именах их не было уже. То есть они ставились автоматически только на то время, пока файл скачался не полностью, а потом так же автоматически убирались, когда он был докачан полностью. Интересно это всё было, и оно работало как часы. Действительно, можно было десятки фильмов тяжёлых качать одновременно, сериалы там всякие с кучей серий в хорошем качестве, и они не перемешивались вообще никак, а качать я там мог их целую неделю или даже больше. Вот эти хеши давали возможность не беспокоиться за совпадающие имена, которые там иногда появлялись у разных фильмов и серий.
robisho
py.user.next
спасибо за идеи) ну у меня не такая глобальная задача будет, нужно будет просто ставить скрипт на паузу в течении одной сессии терминала или стопить. сохранять состояния, думаю не надо.
а каким образом можно реализовать получение сигнала остановки?
например,

 цикл for - выдает ссылки:
    проверка нажатия клавиши P
    проверка нажатия клавиши S
    тело функции 
    проверка нажатия клавиши P
    проверка нажатия клавиши S

так?

а по поводу сохранения ссылок думаю так: индекс ссылки, выданной из for, сохраняется в global temp, и после паузы список редактируется на
 [temp+1:]
.
xam1816
robisho
нужно будет просто ставить скрипт на паузу
Копайте в сторону асинхронного программирования asyncio,
robisho
остановку скрипта можно сделать с помощью модуля msvcrt, отслеживать нажатия клавиш P and S, если S - выходим из скрипта sys.exit(), а если Р - выходим из скрипта sys.exit() с сохранением в файл temp.txt номера использованной строки из файла с линками. следующий запуск скрипта будет начинаться с формирования нового списка линков от temp+1 до конца, если temp.txt не пустой. где могут быть овраги, как считаете?
xam1816
robisho
где могут быть овраги, как считаете?
почему не асинхронное программирование? Оно как раз для таких случаев.
или вот на основе генератора(асинхронность вроде как на основе их и реализована)
  
def my_script():
    print('работает скрипт')
    print('пауза')
    signal = yield
    print('скрипт продолжил работу')
    print(f' еще пришли данные {signal}')
    print(f'скрипт встал на паузу')
    yield
    signal = yield
    print(f'скрипт снова работает c данными {signal}')
script = my_script()
while True:
    try:
        next(script)
        s = input('>')
        script.send(s)
    except StopIteration:
        print('скрипт закончил работу')
        break
 
работает скрипт
пауза
>t
скрипт продолжил работу
еще пришли данные t
скрипт встал на паузу
>4
скрипт снова работает c данными 4
скрипт закончил работу
robisho
xam1816
прошу прощения, вы, наверное, не так поняли. скрипт не должен ВСЕГДА ждать next, он должен выполняться по плану, но отслеживать нажатия клавиш Р и S.
ну примерно так
 lst = [1, 2, 3]
def foo(elem):
    returt elem ** 2
for elem in lst:
    print(foo(elem))

вот во время выполнения цикла for и должно отслеживаться нажатия клавиш. если нажать Р - foo(elem) выполняется и цикл ставится на паузу, если S - просто выход из скрипта, а если не нажали - проходит весь цикл и завершается.
xam1816
сырая модель
  
from pynput.keyboard import Events
def gen():
    i = 0
    while 1:
        i += 1
        yield i
 
def gen_signal():
    with Events() as event:
        while 1:
            s = event.get(1)
            if s:
                if str(s).startswith('Release') and hasattr(s.key, 'char'):
                    yield s.key.char
            else:
                yield None
 
def main():
    signal = gen_signal()
    g = gen()
    f = True
    while 1:
        if f:
            print(next(g))
        s = next(signal)
        if s is not None:
            if s == 'p':
                f = not f
                print('\npause') if not f else print('\ngo')
            elif s == 's':
                print('\nbreak')
                break
 
main()
 
1
2
3
4
p
pause
p
go
5
6
7
s
break

Process finished with exit code 0
robisho
xam1816
сырая модель
очень интересно, спасибо, попробую разобраться)

у меня получилось вот такое

 import msvcrt
import os
def function(elem):
    return elem ** 2
lst = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
for elem in lst:
    is_stop = False
    while True:
        if not is_stop:
            print(function(elem))
            time.sleep(5)
        if msvcrt.kbhit():
            point = msvcrt.getch()
            point_ord = ord(point)
            if point_ord == 112:  # p=112
                print('Key "p" was pressed!')
                if not is_stop:
                    is_stop = True
                    print('Основной цикл остановлен')
                elif is_stop:
                    is_stop = False
                    print('Основной цикл снова запущен')
            elif point_ord == 115:  # s=115
                print('Кирдык!')
                os._exit(1)
            else:
                print('Press "P" for pause, "S" for stop')
        if not is_stop:
            break

все это дело я оформил, как декоратор, теперь можно любую отдельно взятую функцию везде наряжать) спасибо всем комрадам, что откликнулись)
robisho
Добрый день. Вопрос такой возник: можно ли в скрипт, что я выложил выше, после print('Основной цикл остановлен') в этом же if, пока скрипт на паузе, вклинить другой код из этой же программы? допустим, я захотел в этой паузе проверить ссылки в файле, который используется в программе, на работоспособность. спасибо.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB