레이블이 Python pathlib recursive file searches and hidden files인 게시물을 표시합니다. 모든 게시물 표시
레이블이 Python pathlib recursive file searches and hidden files인 게시물을 표시합니다. 모든 게시물 표시

2026년 10월 18일 일요일

Choosing Path.glob(), Path.rglob(), or glob.glob() for file searches

For Python 3.14, choose a search API by the shape of its results as well as its pattern. A script that works with Path objects may favor pathlib; a caller that needs strings relative to a specified search root may favor glob.glob(). The table gives the practical differences before two short examples.

Choosing Path.glob(), Path.rglob(), or glob.glob() for file searches
A reading map of the checks explained below.

Compare the three APIs

Feature | Path.glob() | Path.rglob() | glob.glob() Recursion | Use ** in the pattern | Searches recursively by adding **/ before the pattern | Use ** with recursive=True Hidden components | Wildcards may match dot-prefixed names | Same | Wildcards exclude them by default; include_hidden=True permits them Directory symlinks | ** does not descend through them by default | Same | Recursive ** may traverse them Return type | Iterator of Path objects | Iterator of Path objects | List of strings Root-relative results | Results retain the Path root prefix; use relative_to(root) | Same | With relative pathname and root_dir, results are relative to root_dir

The rows describe Python 3.14’s documented behavior. In particular, a Path.glob() pattern containing ** is recursive, so the method is not inherently limited to one level. Path.rglob() saves you from writing that leading recursive component. For glob.glob(), recursive=True gives ** its recursive meaning; include_hidden=True changes what wildcards may match. Sources: https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.glob, https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.rglob, https://docs.python.org/3.14/library/pathlib.html#comparison-to-the-glob-module, and https://docs.python.org/3.14/library/glob.html#glob.glob.

Sources: pathlib — Object-oriented filesystem paths, glob — Unix style pathname pattern expansion

Choose pathlib for Path objects

Suppose a script checks the immediate contents of assets for PNG files, then separately needs PNG files anywhere below assets: from pathlib import Path root = Path("assets") top_level = list(root.glob("*.png")) any_depth = list(root.rglob("*.png")) Both collections contain Path objects with assets in their displayed paths. If the caller needs names relative to assets, convert each result with path.relative_to(root). The first pattern addresses one level; the second also searches descendants. The equivalent recursive Path.glob() pattern is "**/*.png". See https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.glob and https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.rglob.

Neither pathlib call treats a leading dot as a reason to exclude a matching name. If the intended search should omit files inside .cache or a similarly named directory, apply a rule to the components relative to root, or prune directories with Path.walk(). That policy belongs to the task rather than to the choice between Path.glob() and Path.rglob(). See https://docs.python.org/3.14/library/pathlib.html#comparison-to-the-glob-module.

Sources: pathlib — Object-oriented filesystem paths

Choose glob.glob() for root-relative strings

Suppose a manifest expects strings such as "chapter/notes.txt" relative to a content directory: import glob entries = glob.glob("**/*.txt", root_dir="content", recursive=True) Here root_dir sets the search location, while the relative pathname keeps that root out of each returned string. Leave include_hidden at its default when wildcard matches should omit dot-prefixed components; set include_hidden=True when they should be eligible. The function returns a list, so sort it if the manifest needs a defined order. See https://docs.python.org/3.14/library/glob.html#glob.glob.

A leading directory written in the pathname remains in returned strings when root_dir is not used. For example, glob.glob("content/*.txt") returns strings beginning with content/ for matches to that pattern. Supplying root_dir with a relative pathname is the direct way to express the desired output boundary. See the examples and root_dir description at https://docs.python.org/3.14/library/glob.html#glob.glob.

Sources: glob — Unix style pathname pattern expansion

Check file type, links, and completeness separately

All three searches can yield matching paths that are not regular files. Check file type before treating a match as file content. Link behavior also deserves an explicit decision: pathlib’s recursive ** avoids following directory symlinks by default, while glob.glob() can traverse directory symlinks during recursive ** expansion. For pathlib, recurse_symlinks=True changes the default. See https://docs.python.org/3.14/library/pathlib.html#comparison-to-the-glob-module and https://docs.python.org/3.14/library/glob.html#glob.glob.

These methods can suppress filesystem scanning errors, including permission errors. Their output is a collection of discovered matches, not proof that every directory was inspected. The examples and table summarize documented Python 3.14 behavior; they are not benchmark results or observations from an executed search. See https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.rglob and https://docs.python.org/3.14/library/glob.html#glob.glob.

Sources: pathlib — Object-oriented filesystem paths, glob — Unix style pathname pattern expansion

Primary sources checked: 2026-10-17. Prepared with AI assistance and a separate evidence review. This is documentation-based guidance, not a hands-on test or performance benchmark.

Read the companion guide

Find files recursively with Path.rglob() while excluding hidden paths

Suppose a script needs every .csv file under data, except files whose names or parent directories begin with a dot. In Python 3.14, Path.rglob() finds candidates throughout that tree. A filter then decides which candidates belong in the result. If the script must skip hidden directories during the search itself, use Path.walk() to prune them.

Find files recursively with Path.rglob() while excluding hidden paths
A reading map of the checks explained below.

Filter every component below the root

Here is a complete collection step: from pathlib import Path root = Path("data") files = sorted( path for path in root.rglob("*.csv") if path.is_file() and not any(part.startswith(".") for part in path.relative_to(root).parts) ) The relative_to(root).parts expression examines only the portion beneath data. It rejects data/.cache/report.csv and data/reports/.draft.csv as well as data/.summary.csv. It does not reject every descendant merely because the chosen root itself has a dot-prefixed name. The is_file() check limits the collection to files; by default, it also accepts a symlink whose target is a regular file. See Python 3.14’s Path.rglob() and Path.is_file() documentation: https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.rglob and https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.is_file.

Path.rglob("*.csv") searches at the root and below it, and its results retain the root prefix. The sorted() call gives the script a stable presentation order for the results it receives; the search itself supplies no particular order. See https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.rglob.

Sources: pathlib — Object-oriented filesystem paths

Prune hidden directories before entering them

The filter above still lets the recursive search visit a hidden directory before discarding matches found there. For a search that skips those directories during descent, walk from the same root and edit the directory list: from pathlib import Path root = Path("data") files = [] for directory, dirnames, filenames in root.walk(): dirnames[:] = [name for name in dirnames if not name.startswith(".")] files.extend( directory / name for name in filenames if name.endswith(".csv") and not name.startswith(".") and (directory / name).is_file() ) files.sort() Editing dirnames in place during the default top-down walk prevents Path.walk() from descending into removed directories. The filename check handles hidden files in directories that remain. This example uses a literal .csv ending rather than a glob pattern; if the intended rule is more complex, define it explicitly where filenames are selected. See https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.walk.

Path.walk() does not follow directory symlinks by default. With that default, a link to a directory is placed among filenames, and the is_file() check above leaves it out. If the search needs a different link policy, decide that separately from the hidden-name policy. See https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.walk.

Sources: pathlib — Object-oriented filesystem paths

Choose the exclusion rule deliberately

A hidden path here means a component whose name starts with a dot. A directory called build is visible under that rule, even if the script should ignore it. Add such names to the dirnames filter when using Path.walk(), or add a separate component check when filtering rglob() results. A name like report.v2.csv is also visible because its dot is not at the start.

The examples treat data as the search boundary and allow the caller to choose even a dot-prefixed root. That choice avoids making a relative name test depend on parent directories outside the requested search. If the caller instead wants to reject a hidden root, check root.name before starting. These are application rules, so writing them beside the search makes later changes easier to review.

Sources: pathlib — Object-oriented filesystem paths

Know what a result list establishes

Pathlib wildcards can match dot-prefixed names, and recursive double-star expansion does not follow directory symlinks by default. The recurse_symlinks option changes that traversal choice. See the comparison with glob at https://docs.python.org/3.14/library/pathlib.html#comparison-to-the-glob-module and Path.rglob() at https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.rglob.

Path.rglob() suppresses filesystem scanning errors, including permission errors. Path.walk() also ignores scanning errors by default, but its on_error argument can receive them. A short result list therefore does not establish that every directory was readable. Use on_error when the script needs to detect an incomplete walk. See https://docs.python.org/3.14/library/pathlib.html#pathlib.Path.walk.

Sources: pathlib — Object-oriented filesystem paths

Primary sources checked: 2026-10-17. Prepared with AI assistance and a separate evidence review. This is documentation-based guidance, not a hands-on test or performance benchmark.

Read the companion guide