Уведомления

Группа в Telegram: @pythonsu

#1 Дек. 13, 2022 02:56:43

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

Добрый день. Задача такая: при работе скрипта нужно его остановить, а затем продолжить выполнение с того же места остановки. Например, при парсинге или массовой отправки сообщений smtp. Т.е. структура, я думаю, будет одна: из списка берется url или email и обрабатывается в функции парсинга/smtp. Нужно при остановке скрипта дать функции парсинга/smtp завершиться и остановиться на выдаче очередного url/email, а при повторном запуске начать с точки останова. Подскажите, пожалуйста, как это можно осуществить? Интересуют все возможные теории/названия/библиотеки. Спасибо.

Офлайн

#2 Дек. 13, 2022 04:23:02

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9874
Репутация: +  854  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

robisho
Подскажите, пожалуйста, как это можно осуществить?
Можно сделать по принципу, который есть у браузеров и программ для закачки. Когда она закачивает, она регистрирует все закачанные части. При её остановке остаются эти файлы, в которых записано то последнее, что закачалось. При новом запуске она ищет эти файлы, в которых записано, что там было до этого запуска, и по ним действует дальше, так же их меняя.

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

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



Отредактировано py.user.next (Дек. 13, 2022 04:25:18)

Офлайн

#3 Дек. 13, 2022 05:57:46

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

py.user.next
спасибо за идеи) ну у меня не такая глобальная задача будет, нужно будет просто ставить скрипт на паузу в течении одной сессии терминала или стопить. сохранять состояния, думаю не надо.
а каким образом можно реализовать получение сигнала остановки?
например,

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

так?

а по поводу сохранения ссылок думаю так: индекс ссылки, выданной из for, сохраняется в global temp, и после паузы список редактируется на
 [temp+1:]
.

Отредактировано robisho (Дек. 13, 2022 06:06:53)

Офлайн

#4 Дек. 13, 2022 07:00:05

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1355
Репутация: +  119  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

robisho
нужно будет просто ставить скрипт на паузу
Копайте в сторону асинхронного программирования asyncio,

Офлайн

#5 Дек. 13, 2022 12:16:46

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

остановку скрипта можно сделать с помощью модуля msvcrt, отслеживать нажатия клавиш P and S, если S - выходим из скрипта sys.exit(), а если Р - выходим из скрипта sys.exit() с сохранением в файл temp.txt номера использованной строки из файла с линками. следующий запуск скрипта будет начинаться с формирования нового списка линков от temp+1 до конца, если temp.txt не пустой. где могут быть овраги, как считаете?

Офлайн

#6 Дек. 13, 2022 16:54:34

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1355
Репутация: +  119  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

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
скрипт закончил работу

Офлайн

#7 Дек. 14, 2022 05:27:51

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

xam1816
прошу прощения, вы, наверное, не так поняли. скрипт не должен ВСЕГДА ждать next, он должен выполняться по плану, но отслеживать нажатия клавиш Р и S.
ну примерно так
 lst = [1, 2, 3]
def foo(elem):
    returt elem ** 2
for elem in lst:
    print(foo(elem))

вот во время выполнения цикла for и должно отслеживаться нажатия клавиш. если нажать Р - foo(elem) выполняется и цикл ставится на паузу, если S - просто выход из скрипта, а если не нажали - проходит весь цикл и завершается.

Офлайн

#8 Дек. 14, 2022 20:52:26

xam1816
Зарегистрирован: 2020-05-11
Сообщения: 1355
Репутация: +  119  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

сырая модель

  
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

Офлайн

#9 Дек. 15, 2022 06:16:26

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

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

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

Офлайн

#10 Дек. 19, 2022 06:12:07

robisho
Зарегистрирован: 2020-10-19
Сообщения: 60
Репутация: +  2  -
Профиль   Отправить e-mail  

Прерывание скрипта и повторный запуск

Добрый день. Вопрос такой возник: можно ли в скрипт, что я выложил выше, после print('Основной цикл остановлен') в этом же if, пока скрипт на паузе, вклинить другой код из этой же программы? допустим, я захотел в этой паузе проверить ссылки в файле, который используется в программе, на работоспособность. спасибо.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version