【问题标题】:python pyinotify to monitor the specified suffix files in a dirpython pyinotify 监控某个目录下的指定后缀文件
【发布时间】:2013-08-20 17:34:00
【问题描述】:

我想监控一个目录,该目录有子目录,子目录中有一些带有.md 的文件。 (可能还有一些其他的文件,比如*.swp...)

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

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

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

这是我写的主要代码:

!/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

【问题讨论】:

    标签: python inotify pyinotify


    【解决方案1】:

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

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

    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)
    

    【讨论】:

    • 我之前评论说我无法让它工作,但现在我明白了。您需要编辑SUFFIXES 并删除*(否则它永远不会匹配)并在fn.name 上调用splitext,因为pevent 可调用对象将Event 作为其参数。 +1,比我的解决方案更好,我实际上尝试用pevent 解决这个问题,但由于某种原因无法让它工作。
    • 非常感谢,这种方式太酷了!代码中有一点错误。当使用suffix_filter作为pevent的回调时,suffix_filter的参数是event,所以应该是os.path.splitext(fn.name)[1]
    • Tanky,@Paulo:感谢您指出编码错误。我尽可能不发布未经测试的内容,但在这种情况下不能发布,因为我的操作系统没有 inotify。
    【解决方案2】:

    您的解决方案没有什么特别的问题,但您希望您的 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.splitext 和集合搜索比迭代 fnmatch 更快,但对于您非常小的扩展列表而言,这可能不是真的 - 您应该对其进行测试。

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

    【讨论】:

    【解决方案3】:

    可以使用ProcessEvent__call__方法集中调用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
    

    【讨论】:

      猜你喜欢
      • 2015-10-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多