mirror of
https://github.com/python/cpython.git
synced 2025-12-09 18:48:05 +00:00
New generator os.walk() does a bit more than os.path.walk() does, and
seems much easier to use. Code, docs, NEWS, and additions to test_os.py (testing this sucker is a bitch!).
This commit is contained in:
parent
e7adda9035
commit
c4e0940042
5 changed files with 242 additions and 5 deletions
81
Lib/os.py
81
Lib/os.py
|
|
@ -26,6 +26,7 @@ import sys
|
|||
|
||||
_names = sys.builtin_module_names
|
||||
|
||||
# Note: more names are added to __all__ later.
|
||||
__all__ = ["altsep", "curdir", "pardir", "sep", "pathsep", "linesep",
|
||||
"defpath", "name", "path"]
|
||||
|
||||
|
|
@ -158,7 +159,7 @@ def removedirs(name):
|
|||
Super-rmdir; remove a leaf directory and empty all intermediate
|
||||
ones. Works like rmdir except that, if the leaf directory is
|
||||
successfully removed, directories corresponding to rightmost path
|
||||
segments will be pruned way until either the whole path is
|
||||
segments will be pruned away until either the whole path is
|
||||
consumed or an error occurs. Errors during this latter phase are
|
||||
ignored -- they generally mean that a directory was not empty.
|
||||
|
||||
|
|
@ -202,6 +203,84 @@ def renames(old, new):
|
|||
|
||||
__all__.extend(["makedirs", "removedirs", "renames"])
|
||||
|
||||
def walk(top, topdown=True):
|
||||
"""Directory tree generator.
|
||||
|
||||
For each directory in the directory tree rooted at top (including top
|
||||
itself, but excluding '.' and '..'), yields a 3-tuple
|
||||
|
||||
dirpath, dirnames, filenames
|
||||
|
||||
dirpath is a string, the path to the directory. dirnames is a list of
|
||||
the names of the subdirectories in dirpath (excluding '.' and '..').
|
||||
filenames is a list of the names of the non-directory files in dirpath.
|
||||
Note that the names in the lists are just names, with no path components.
|
||||
To get a full path (which begins with top) to a file or directory in
|
||||
dirpath, do os.path.join(dirpath, name).
|
||||
|
||||
If optional arg 'topdown' is true or not specified, the triple for a
|
||||
directory is generated before the triples for any of its subdirectories
|
||||
(directories are generated top down). If topdown is false, the triple
|
||||
for a directory is generated after the triples for all of its
|
||||
subdirectories (directories are generated bottom up).
|
||||
|
||||
When topdown is true, the caller can modify the dirnames list in-place
|
||||
(e.g., via del or slice assignment), and walk will only recurse into the
|
||||
subdirectories whose names remain in dirnames; this can be used to prune
|
||||
the search, or to impose a specific order of visiting. Modifying
|
||||
dirnames when topdown is false is ineffective, since the directories in
|
||||
dirnames have already been generated by the time dirnames itself is
|
||||
generated.
|
||||
|
||||
Caution: if you pass a relative pathname for top, don't change the
|
||||
current working directory between resumptions of walk. walk never
|
||||
changes the current directory, and assumes that the client doesn't
|
||||
either.
|
||||
|
||||
Example:
|
||||
|
||||
from os.path import join, getsize
|
||||
for root, dirs, files in walk('python/Lib/email'):
|
||||
print root, "consumes",
|
||||
print sum([getsize(join(root, name)) for name in files]),
|
||||
print "bytes in", len(files), "non-directory files"
|
||||
if 'CVS' in dirs:
|
||||
dirs.remove('CVS') # don't visit CVS directories
|
||||
"""
|
||||
|
||||
from os.path import join, isdir, islink
|
||||
|
||||
# We may not have read permission for top, in which case we can't
|
||||
# get a list of the files the directory contains. os.path.walk
|
||||
# always suppressed the exception then, rather than blow up for a
|
||||
# minor reason when (say) a thousand readable directories are still
|
||||
# left to visit. That logic is copied here.
|
||||
try:
|
||||
# Note that listdir and error are globals in this module due
|
||||
# to earlier import-*.
|
||||
names = listdir(top)
|
||||
except error:
|
||||
return
|
||||
|
||||
dirs, nondirs = [], []
|
||||
for name in names:
|
||||
if isdir(join(top, name)):
|
||||
dirs.append(name)
|
||||
else:
|
||||
nondirs.append(name)
|
||||
|
||||
if topdown:
|
||||
yield top, dirs, nondirs
|
||||
for name in dirs:
|
||||
path = join(top, name)
|
||||
if not islink(path):
|
||||
for x in walk(path, topdown):
|
||||
yield x
|
||||
if not topdown:
|
||||
yield top, dirs, nondirs
|
||||
|
||||
__all__.append("walk")
|
||||
|
||||
# Make sure os.environ exists, at least
|
||||
try:
|
||||
environ
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue