PurePath.match与Path.glob的差异及断言失败问题咨询
API功能说明
PurePath.match(pattern):将路径与指定glob风格模式匹配,匹配成功返回True,否则返回False。注意这里的**通配符要求匹配至少一层子目录。Path.glob(pattern):在当前路径对应的目录中匹配给定模式,生成所有匹配的任意类型文件。这里的**通配符允许匹配零层或多层子目录(也就是包含目标目录本身的直接子文件)。
问题1:为何断言会失败?
这两个API对**通配符的处理逻辑差异,是导致断言失败的核心原因:
Path('../').glob("sql-queries/**/*.sql")会返回sql-queries目录下所有.sql文件——包括直接放在sql-queries根目录下的文件(比如../sql-queries/combined_gv.sql),以及所有子目录里的.sql文件(比如../sql-queries/gen_test_data/combined_gv.sql)。因为glob的**允许匹配零层子目录(即目标目录本身)。- 而
fname.match("sql-queries/**/*.sql")只会匹配那些在sql-queries子目录里的.sql文件。因为match的**要求至少匹配一层子目录,直接放在sql-queries根目录下的文件(没有子目录层级)无法满足这个模式,会被过滤掉。
最终filtered_files只包含子目录中的文件,而query_files包含根目录和子目录的所有匹配文件,两者内容不相等,断言自然失败。
问题2:如何修改PurePath.match的匹配模式?
要让断言成立,我们需要让match的模式同时覆盖两种情况:直接在sql-queries根目录下的文件,以及子目录里的文件。最直接的修改方式是使用两个模式做逻辑或:
filtered_files = [fname for fname in query_files if fname.match("sql-queries/*.sql") or fname.match("sql-queries/**/*.sql")]
"sql-queries/*.sql"负责匹配sql-queries根目录下的直接子文件;"sql-queries/**/*.sql"负责匹配所有子目录里的.sql文件。
这样就能保证filtered_files和query_files的内容完全一致,断言不会失败。
示例说明
问:能否给出一个存在于query_files但不在filtered_files中的具体路径?
答:
比如PosixPath('../sql-queries/combined_gv.sql')——这个文件直接放在sql-queries根目录下,无法通过fname.match("sql-queries/**/*.sql")的匹配,所以会出现在query_files里,但不会被纳入filtered_files。
对应的完整列表示例:
query_files = <class 'list'>: [ PosixPath('../sql-queries/combined_gv.sql'), PosixPath('../sql-queries/gv_with_merchant.sql'), PosixPath('../sql-queries/merchant_dimension.sql'), PosixPath('../sql-queries/gen_test_data/combined_gv.sql'), PosixPath('../sql-queries/gen_test_data/merchant_dimension.sql')] filtered_files = <class 'list'>: [ PosixPath('../sql-queries/gen_test_data/combined_gv.sql'), PosixPath('../sql-queries/gen_test_data/merchant_dimension.sql')]
内容的提问来源于stack exchange,提问作者Abhijit
相关产品推荐
相关产品推荐

