如果路径在python中的包含或排除列表中的最佳方法

时间:2013-10-31 21:17:11

标签: python watchdog

我正在编写一个python程序来备份一系列监视目录中的文件。 我正在使用Watchdog来检测文件系统的更改。所有提供的是已更改的文件和文件夹列表。

应用程序可以选择包含和排除文件夹列表,但我无法确定如何匹配路径以查看它们是否应被排除或包含在内。

问题是当你有一棵树并且用户选择包含一个被排除的文件夹时。

示例文件树

/folder1/folder2/folder3/folder4/folder5


/folder1
/folder1/folder2/folder3/folder4

排除了

/folder1/folder2

我想过使用startswith()来比较看门狗返回的字符串的路径部分的开头,但是/folder1/folder2/folder3/folder4/folder5将匹配包含和排除文件夹列表。

如果有人能提出最好的解决方法,我将非常感激。如果我使用os.walk来通过目录进行递归,但我只能给出一个列表,我无法弄清楚如何做到这一点,我可以让它轻松工作。它让我疯狂。

3 个答案:

答案 0 :(得分:1)

如果我理解你在说什么,你想优先考虑最嵌套的深度。因此'/folder1/folder2/folder3/folder4/folder5 包含

我会将您的数据放入这样的查找表中:

lookup = {'/folder1/folder2/folder3/folder4':'include','/folder1/folder2':'exclude','/folder1':'include'}

然后以相反的顺序循环查询,一次剥离一个目录,直到你得到一个匹配:

folder = '/folder1/folder2/folder3/folder4/folder5'.split('/')
for i in reversed(range(len(folder) + 1)):
    check = '/'.join(folder[:i])
    if lookup.get(check):
        print('{}: {}'.format(check,lookup.get(check)))
        break

#/folder1/folder2/folder3/folder4: include

答案 1 :(得分:0)

假设路径f,如果我理解你的问题,这可能会有效

f.startswith(tuple(includes)) and not f.startswith(tuple(excludes))

答案 2 :(得分:0)

作为另一种可能性,应该应用于任何给定路径的动作(即包括或排除)是最具体的。因此,您可以通过将配置放在以下结构中来解决问题:

rules = [("/folder1", "include"), ("/folder1/folder2/...", "exclude"), ...]

然后,您可以使用以下函数确定要对给定路径应用的操作:

def get_action(path, rules):
    action = None
    depth = None
    for filter, filter_action in rules:
        if path.startswith(filter):
            filter_depth = filter.count(os.sep)
            if depth is None or filter_depth > depth:
                depth = filter_depth
                action = filter_action
    return action

然后,这将返回操作,即“包含”或“排除”,或者如果没有为路径None定义规则。我给出的定义是相当低效的,并且有很多方法可以改进,但基本的想法是为给定的路径寻找最具体的规则并遵循该行动。