методы pyinotify не вызываются

Я хочу создать модуль, который будет следить за папкой. Я пишу часть кода:

import os, pyinotify

class FileWatcher:
    def start_watch(self, dir):
        wm = pyinotify.WatchManager()
        self.notifier = pyinotify.Notifier(wm, EventProcessor())
        mask = pyinotify.IN_CREATE | pyinotify.IN_MODIFY | pyinotify.IN_DELETE | pyinotify.IN_DELETE_SELF | pyinotify.IN_MOVED_FROM | pyinotify.IN_MOVED_TO
        wdd = wm.add_watch(dir, mask, rec=True)
        while True:
            self.notifier.process_events()
            if self.notifier.check_events():
                self.notifier.read_events()

    def stop_watch(self):
        self.notifier.stop()
        print ('\nWatcher stopped')

class EventProcessor(pyinotify.ProcessEvent):
    def process_IN_CREATE(self, event):
        print('in CREATE')

    def process_IN_MODIFY(self, event):
        print('in MODIFY')

    def process_IN_DELETE(self, event):
        print('in delete')

    def process_IN_DELETE_SELF(self, event):
        print('in delete self')

    def process_IN_MOVED_FROM(self, event):
        print('in MOVED_FROM')

    def process_IN_MOVED_TO(self, event):
        print('in IN_MOVED_TO')

if __name__ == "__main__":
    watcher = FileWatcher()
    try:
        folder = "/home/user/Desktop/PythonFS"
        watcher.start_watch(folder)
    except KeyboardInterrupt:
        watcher.stop_watch()    

Когда я изменил файл, а затем удалил его, методы process_IN_MODIFY и process_IN_DELETE никогда не вызывались. Как мне это решить?

Но когда я создаю файл, вызывается метод process_IN_CREATE().

ОС - линукс минт 13.

UPD: новый код


person Vetalll    schedule 26.03.2013    source источник
comment
Гм, этот код синтаксически недействителен (отступ отсутствует, просто вставьте его, выберите его и нажмите Ctrl+K), и он только определяет классы и функции и не вызывает ни одну из них.   -  person phihag    schedule 26.03.2013
comment
Это синтаксически верный код. Методы должны вызываться из уведомителя, потому что я помещаю экземпляр EventProcessor в конструктор pyinotify.Notifier(...)   -  person Vetalll    schedule 26.03.2013
comment
Нет. И почему там есть некоторые вызываемые функции, код на самом деле их не вызывает.   -  person phihag    schedule 26.03.2013
comment
ой, извини. Парсер кода работает плохо. И ctrl+k мне не помогает. Я изменил эту строку.   -  person Vetalll    schedule 26.03.2013
comment
stop_watch и start_watch вызываются из другого модуля. Это простой запуск и остановка. Я думаю, они не касаются моей проблемы.   -  person Vetalll    schedule 26.03.2013
comment
Если это так, вы сможете воспроизвести проблему с упрощенной версией. Если проблема возникает только тогда, когда вы вызываете функции запуска/остановки из другого модуля, вам необходимо опубликовать этот модуль.   -  person phihag    schedule 26.03.2013
comment
Я разместил новый код с той же проблемой.   -  person Vetalll    schedule 26.03.2013


Ответы (1)


Попробуйте следующий код. Это в основном то же самое, что и ваш код; я только добавил

f = FileWatcher()
f.start_watch('/tmp/test', None)

в конце, чтобы начать FileWatcher. Убедитесь, что каталог /tmp/test существует, или измените эту строку так, чтобы она указывала на существующий каталог.

Если файл foo существует в /tmp/test, и если я изменяю этот файл, вышеуказанная программа печатает

in create   # after modification
in modify   # after saving
in modify
in delete

Теперь, если я удалю файл, программа напечатает:

in delete

import os
import pyinotify


class FileWatcher:
    notifier = None

    def start_watch(self, dir, callback):
        wm = pyinotify.WatchManager()
        self.notifier = pyinotify.Notifier(wm, EventProcessor(callback))
        mask = (pyinotify.IN_CREATE | pyinotify.IN_MODIFY | pyinotify.IN_DELETE
                | pyinotify.IN_DELETE_SELF | pyinotify.IN_MOVED_FROM
                | pyinotify.IN_MOVED_TO)
        wdd = wm.add_watch(dir, mask, rec=True)
        while True:
            self.notifier.process_events()
            if self.notifier.check_events():
                self.notifier.read_events()


class EventProcessor(pyinotify.ProcessEvent):
    def __init__(self, callback):
        self.event_callback = callback

    def process_IN_CREATE(self, event):
        # if self.event_callback is not None:
        # self.event_callback.on_file_created(os.path.join(event.path,
        # event.name))
        print('in create')

    def process_IN_MODIFY(self, event):
        # if self.event_callback is not None:
        # self.event_callback.on_file_modifed(os.path.join(event.path,
        # event.name))
        print('in modify')

    def process_IN_DELETE(self, event):
        print('in delete')

    def process_IN_DELETE_SELF(self, event):
        print('in delete self')

    def process_IN_MOVED_FROM(self, event):
        print('in moved_from')

    def process_IN_MOVED_TO(self, event):
        print('in moved to')


f = FileWatcher()
f.start_watch('/tmp/test', None)

Кстати, как только вы вызываете f.start_watch, процесс попадает в цикл while True, из которого он не может выбраться. Даже вызов f.stop_watch из другого потока не вырвет вас из этого цикла while.

Если вы планируете использовать многопоточность, вам может потребоваться передать threading.Event в start_watch и проверить его состояние внутри while-loop, чтобы определить, когда выйти из цикла.

person unutbu    schedule 26.03.2013