0

我想监视一个 dir ,该 dir 有 sub dirs 并且在 subdir 中有一些带有.md. (可能还有一些其他的文件,比如*.swp...)

我只想监视 .md 文件,我已经阅读了文档,并且只有一个ExcludeFilter, 并且在问题中:https ://github.com/seb-m/pyinotify/issues/31说,只有 dir 可以过滤但不是文件。

现在我要做的是过滤process_*函数以检查event.nameby fnmatch

那么如果我只想监控指定后缀的文件,有没有更好的办法呢?谢谢。

这是我写的主要代码:

!/usr/bin/env python                                                                                                                                
# -*- coding: utf-8 -*-

import pyinotify                                                                    
import fnmatch                                                                      

def suffix_filter(fn):                                                              
    suffixes = ["*.md", "*.markdown"]                                                                                                                
    for suffix in suffixes:                                                         
        if fnmatch.fnmatch(fn, suffix):                                             
            return False                                                            
    return True                                                                     

class EventHandler(pyinotify.ProcessEvent):                                         
    def process_IN_CREATE(self, event):                                             
        if not suffix_filter(event.name):                                           
            print "Creating:", event.pathname                                       

    def process_IN_DELETE(self, event):                                             
        if not suffix_filter(event.name):                                           
            print "Removing:", event.pathname                                       

    def process_IN_MODIFY(self, event):                                             
        if not suffix_filter(event.name):                                           
            print "Modifing:", event.pathname                                       

    def process_default(self, event):                                               
        print "Default:", event.pathname
4

3 回答 3

2

我认为你基本上有正确的想法,但它可以更容易地实施。

pyinotify模块中的ProcessEvent类已经有一个钩子,您可以使用它来过滤事件的处理。它是通过在调用构造函数时给出的可选关键字参数指定的,并保存在实例的属性中。默认值为。它的值在类的方法中使用,如源文件中的以下片段所示:peventself.peventNone__call__()pyinotify.py

def __call__(self, event):
    stop_chaining = False
    if self.pevent is not None:
        # By default methods return None so we set as guideline
        # that methods asking for stop chaining must explicitly
        # return non None or non False values, otherwise the default
        # behavior will be to accept chain call to the corresponding
        # local method.
        stop_chaining = self.pevent(event)
    if not stop_chaining:
        return _ProcessEvent.__call__(self, event)

所以你可以使用它只允许具有某些后缀(又名扩展名)的文件的事件,如下所示:

SUFFIXES = {".md", ".markdown"}

def suffix_filter(event):
    # return True to stop processing of event (to "stop chaining")
    return os.path.splitext(event.name)[1] not in SUFFIXES

processevent = ProcessEvent(pevent=suffix_filter)
于 2013-08-19T07:54:15.543 回答
1

您的解决方案没有什么特别的问题,但是您希望您的 inotify 处理程序尽可能快,因此您可以进行一些优化。

您应该将匹配后缀移出函数,因此编译器只构建它们一次:

EXTS = set([".md", ".markdown"])

我将它们设置为一组,以便您可以进行更有效的匹配:

def suffix_filter(fn):
  ext = os.path.splitext(fn)[1]
  if ext in EXTS:
    return False
  return True

我只是假设os.path.splitextset search 比 iterative 更快fnmatch,但这对于你真正小的扩展列表可能不是真的 - 你应该测试它。

(注意:我已经在上面镜像了您的代码,当您进行匹配时返回 False,但我不相信这是您想要的 - 至少对于阅读您的代码的人来说不是很清楚)

于 2013-08-19T01:06:06.027 回答
1

您可以使用 的__call__方法ProcessEvent来集中调用suffix_filter

class EventHandler(pyinotify.ProcessEvent):
    def __call__(self, event):
        if not suffix_filter(event.name):
            super(EventHandler, self).__call__(event)

    def process_IN_CREATE(self, event):
        print "Creating:", event.pathname

    def process_IN_DELETE(self, event):
        print "Removing:", event.pathname

    def process_IN_MODIFY(self, event):
        print "Modifying:", event.pathname
于 2013-08-19T02:05:16.810 回答