【问题标题】:Generating multiple observers with Python watchdog使用 Python 看门狗生成多个观察者
【发布时间】:2013-11-15 00:08:01
【问题描述】:

我目前有一个基本功能脚本,用于监视单个目录和下面的所有子目录的更改并将输出传递给 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()

从我从初始运行中收集到的信息来看,输出似乎显示了列表中指定的所有三个路径名的变化,但我需要编写一些测试代码来检查。

我仍然不确定这是如何表现的,所以任何进一步的 cmets 都会很棒。

干杯。

附加 3:

我将 FogleBird 的答案标记为最佳答案,因为它只是唯一一个并且确实突出了我最初代码的问题。

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

【问题讨论】:

  • 您找到解决方法了吗?我正在尝试实现同样的事情。
  • 嗨 - 是的,上面帖子中的最后一段代码证明是有效的。标记为“附加 2”的部分下方的所有内容都对我有用。

标签: python class watchdog


【解决方案1】:

很好的问题。该线程较旧,但我在查找确切内容时发现了它,并且我扩展了您的工作并添加了传递带有要观看的目录列表的文件的功能。默认情况下,我不递归查看,我将其留给其他人进行测试。希望这可以帮助任何查找相同主题的人。干得好!

使用 python watcher.py 文件名运行。

watcher.py 是我的脚本,而文件名是包含我的路径的文件的名称。

我列出了文件中的完整路径,它们用换行符分隔。

即:

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

watcher.py

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】:

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

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

    此外,您可能应该只在 for 循环之后调用一次 start,而不是在其中。

    【讨论】:

    • 谢谢@FogleBird 我不知道在阅读文档时我在哪里找到了codestart_new_threadcode
    【解决方案3】:

    只是想添加一些注释:

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

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

    就是这样。

    【讨论】:

    • 这为我节省了很多时间!谢谢
    【解决方案4】:

    这是我用来查看多个目录的代码。

    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()
    

    【讨论】:

    • 这个答案是针对同一目录下的多个目录的情况,因此 recursive=True 标志。这与问题所问的不同。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2013-03-05
    • 2019-08-20
    相关资源
    最近更新 更多