使用Python看门狗生成多个观察者

时间:2013-11-15 00:08:02

标签: python class 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()

不幸的是,我收到一条错误,表明观察者没有属性'start_new_thread'

文档中没有示例显示监视目录的多个观察者。我没有处理线程的经验,我甚至不确定我是否在正确的轨道上。

我应该为每条路径创建一个观察者类的新实例吗?或者是否有一些方法可以为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的答案标记为最佳答案,因为它只是唯一一个,并突出了我的初始代码的问题。

我之前的编辑包括完全正常工作的代码,用于监控多个位置,目前似乎正常运行。

4 个答案:

答案 0 :(得分:5)

此处的示例代码显示了一个名为start的函数,而不是start_new_thread。你试过了吗?

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

另外,你应该在for循环之后只调用start一次,而不是在其中。

答案 1 :(得分:4)

好问题。这个帖子比较老,但是在找到确切的东西的时候我找到了它,并且我扩展了你的工作,并添加了传递一个文件,其中包含要监视的目录列表。默认情况下,我不会递归,我将其留给别人测试。希望这有助于任何人查找相同的主题。干得好!

使用python watcher.py filename

运行

在watcher.py中,我称之为脚本,文件名是包含路径的文件的名称。

我列出了文件中的完整路径,这些路径由换行符分隔 即,

C:\ PATH1
C:\路径2 \ 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()

答案 2 :(得分:1)

只想添加一些注意事项:

代码中的线程lib和线程列表对于刚开始使用看门狗(包括我自己)的人来说可能有点混乱。它们在解决方案中实际上不是必需的。解释它的一个简单方法就是:

  • 创建一个观察者
  • 安排多个“观看活动”
  • 并启动观察员。

就是这样。

答案 3 :(得分:0)

这是我用来监视多个目录的代码。

import sys
import time
import logging
from watchdog.observers.polling import PollingObserver as Observer
from watchdog.events import LoggingEventHandler

if __name__ == "__main__":
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s - %(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S')
    event_handler = LoggingEventHandler()
    observer = Observer()
    if len(sys.argv) > 1:
        for i in range(1, len(sys.argv)):
            observer.schedule(event_handler, sys.argv[i], recursive=True)
    else:
        observer.schedule(event_handler, '.', recursive=True)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()