Создание нескольких наблюдателей с помощью Python watchdog

в настоящее время у меня есть базовый функционирующий скрипт, который отслеживает один каталог и все подкаталоги ниже для изменений и передает вывод LoggingEventHandler.

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

Я попытался сделать что-то вроде следующего:

import time
import thread
import threading
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

event_handler = LoggingEventHandler()
observer = Observer()

paths = ["C:dir1", "C:dir2", "C:dir3"]

for i in paths:
    targetPath = str(i)
    observer.schedule(event_handler, targetPath, recursive=True)
    observer.start_new_thread()

к сожалению, я получил сообщение об ошибке указание на то, что observer не имеет атрибута 'start_new_thread'

в документации нет примера, который показывает более одного наблюдателя, контролирующего каталог. У меня нет опыта работы с потоками и я даже не уверен, если я на правильном пути.

должен ли я вместо этого создавать новый экземпляр класса observer для каждого пути? Или есть какой-то метод подачи одного экземпляра класса Observer, множественного пути?

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

дополнительные:

благодаря @FogleBird я исправил проблему запуска потока, но я все еще застрял только с одним экземпляром, а не с тремя отдельными наблюдателями, наблюдающими за разными путями. Мой измененный код теперь выглядит так:

threads = []

for i in paths:
    targetPath = str(i)
    observer.schedule(event_handler, targetPath, recursive=True)
    threads.append(observer)

observer.start()
print threads

Это возвращает три объекта ObservedWatch, но все они имеют те же детали:

[<Observer(Thread-1, started daemon 1548)>, <Observer(Thread-1, started daemon 1548)>, <Observer(Thread-1, started daemon 1548)>]

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

дополнительные 2:

Я продолжал возиться с кодом, и теперь у меня есть что-то, что кажется функциональным:

event_handler = LoggingEventHandler()
N2watch = Observer()
threads = []

for i in paths:
    targetPath = str(i)
    N2watch.schedule(event_handler, targetPath, recursive=True)
    threads.append(N2watch)

N2watch.start()

try:
    while True:
            time.sleep(1)
except KeyboardInterrupt:
    N2watch.stop()
N2watch.join()

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

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

Ура.

дополнительные 3:

я отметил ответ FogleBird как лучший, потому что он был просто единственным и выделил проблемы с моим начальным кодом.

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

3 ответов


в примере кода здесь показана функция с именем start, а не start_new_thread. Ты пробовал?

https://pypi.python.org/pypi/watchdog

кроме того, вы, вероятно, следует называть start только один раз, после цикла, а не внутри него.


большой вопрос. Этот поток старше, но я нашел его, глядя на точную вещь, и я расширил вашу работу и добавил возможность передать файл со списком каталогов для просмотра. По умолчанию я не смотрю рекурсивно, я оставляю это кому-то другому для тестирования. Надеюсь, это поможет любому, кто ищет ту же тему. Отличная работа!

выполнить с помощью python watcher.py имя файла

где watcher.py это то, что я назвал своим скриптом, а filename-это имя файла с моими путями.

я перечисляю полные пути в файле, и они разделены новыми строками Т. е.,

C:\path1
C:\Path2\subpath1
C:\PATH3

import logging
import sys
import time
from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler


# Attach a logging event AKA FileSystemEventHandler
event_handler = LoggingEventHandler()
# Create Observer to watch directories
observer = Observer()
# take in list of paths.  If none given, watch CWD
paths = open(sys.argv[1], 'r') if len(sys.argv) > 1 else '.'
# Empty list of observers .
observers = []
# Base logging configuration
logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S')

# iterate through paths and attach observers
for line in paths:
    # convert line into string and strip newline character
    targetPath = str(line).rstrip()
    # Schedules watching of a given path
    observer.schedule(event_handler, targetPath)
    # Add observable to list of observers
    observers .append(observer)

# start observer
observer.start()

try:
    while True:
        # poll every second
        time.sleep(1)
except KeyboardInterrupt:
    for o in observers:
        o.unschedule_all()
        # stop observer if interrupted
        o.stop()
for o in observers:
    # Wait until the thread terminates before exit
    o.join()

просто хочу добавить некоторые замечания:

список потоков lib и потоков в коде может быть немного запутанным для людей, которые только начинают использовать watchdog (включая меня). Они на самом деле не нужны в решении. Простой способ объяснить это просто:

  • создать один наблюдатель
  • расписание нескольких "Просмотр событий"
  • и начать наблюдателя.