• Как правильно завершить процесс и все дочерние подпроцессы?

    Vindicar
    @Vindicar
    RTFM!
    В-нулевых, не прячь импорты, не всегда понятно что откуда берётся.
    Во-первых, зачем тебе два уровня вложенности в процессах? Сначала делаешь дочерний процесс через multiprocessing.Process, а потом в нём запускаешь еще один процесс через Popen. Смысл? Собственно, результат предсказуем - ты жестко прибиваешь (kill()) первый дочерний процесс, и он не успевает ничего сделать со вторым.
    Во-вторых, Popen уже имеет полезные методы типа terminate(). Но тут есть тонкость - под линуксом этот метод посылает сигнал SIGTERM, на который процесс может отреагировать и спокойно завершить свою работу. Под виндой используется функция WinAPI TerminateProcess(), которая жёстко прибивает процесс, не давая ему шанса завершить работу. Будет практичнее использовать метод signal() в сочетании с константой signal.CTRL_C_EVENT - это будет эквивалентом нажатия Ctrl-C (или Ctrl-Break) в консоли дочернего процесса. Большинство процессов реагируют на это завершением работы. Но под виндой надо будет указать дополнительный параметр для Popen(), чтобы это сработало.

    Так что я бы попробовал что-то в таком духе:
    import signal
    import subprocess
    import sys
    
    args = [
        "ffmpeg", 
        "-i", f"rtsp://{camera_login}:{camera_pass}@{camera_host}:554/Streaming/channels/1/", 
        "-err_detect", "ignore_err", 
        "-reorder_queue_size", "0", 
        "-map", "0:v", "-c:v", "copy", 
        "-f", "rtsp", 
        "-rtsp_transport", "tcp", f"rtsp://{rtsp_server}:8554/live.stream"
    ]
    params = {'cwd': '.'}
    if sys.platform == 'win32':  # винда у нас особенная...
        params['creationflags'] = (
            # subprocess.DETACHED_PROCESS |  # если хочешь, чтобы ffmpeg запускался тихо и не спамил в твой stdout
            # subprocess.CREATE_NEW_CONSOLE |  # если хочешь, чтобы открывалась новая консоль для ffmpeg
            subprocess.CREATE_NEW_PROCESS_GROUP  # по докам, это требуется для нормальной работы ctrl-c
        )
    my_subprocess = Popen(args, **params)
    try:
        pass # тут работаешь с процессом
    finally:
        my_subprocess.signal(signal.CTRL_C_EVENT)  # сигналим процессу о завершении
        try:
            my_subprocess.wait(timeout=5.0)  # ждём завершения
        except subprocess.TimeoutExpired:  # процесс "задумался"
            my_subprocess.kill()  # тогда прибиваем
    Ответ написан
    Комментировать
  • Docker образ на основе python требует обращение к папке через "/". Но я писал код на windows, как можно это исправить?

    @stepanof23
    DevOps/DataOps
    Можно задать переменную delimiter, которой будет присваиваться значение '/' на линуксе и '\' на windows
    Проверять систему можно с помощью platform из библиотеки sys
    Таким образом в процессе кодинга в качестве разделителя всегда будет использоваться одно и то же - переменная delimiter.

    from sys import platform
    if platform == "linux" or platform == "linux2":
        delimiter = '/'
    elif platform == "win32":
        delimiter = '\'
    path = delimiter + 'offers'
            if os.listdir(path):
    Ответ написан
    Комментировать
  • Docker образ на основе python требует обращение к папке через "/". Но я писал код на windows, как можно это исправить?

    Vindicar
    @Vindicar
    RTFM!
    Почитать документацию, конечно.
    Либо собирай пути через pathlib, либо через os.path, на совсем худой конец есть os.sep.
    Ответ написан
    1 комментарий
  • Как запустить скрипт из консоли? Возникает ошибка ImportError: cannot import name 'types' from 'telebot' (C:\..telebot\__init__.py?

    @JRBRO
    Я тоже бился с этим... хрен знает что с этой библиотекой, писал и в корень, и в папку, не робило.

    Использую VENV, самое простое- в pyCharm, если новичек, лучше сразу пробовать VENV не привыкая к плохому.

    Установи pycharm, создай проект, перекинь свой скрипт, запусти в нем консольку и тогда установи pytelegrambotapi
    Ответ написан
    4 комментария
  • Как вывести среднюю высоту статуи?

    Dr_Elvis
    @Dr_Elvis Куратор тега Python
    В гугле забанен
    total_height = 0
    for item in monuments:
        total_height += item['height']
    print(total_height/len(monuments))
    Ответ написан
    3 комментария