Entry
DirectoryList class
Jul 5th, 2000 10:00
Nathan Wallace, Hans Nowak, Snippet 153, Neelakantan Krishnaswami
"""
Packages: operating_systems.generic;oop
"""
"""
One thing I find myself frequently (okay, twice) doing is trying to
walk a directory tree and do stuff in each directory. It was an annoying
enough chore that I wrote a small class to kill it once and for all,
and now I'm sharing. :)
So now you can write things like
l = DirectoryList('c:/Program Files/NTemacs')
for dir in l:
for filename in glob.glob(dir + '/*.el'):
replace_elisp_with_python(filename)
and replace_elisp_with_python() will get called on every .el file
in c:\program files\ntemacs and its subdirectories.
"""
# Name: DirectoryList.py
# Purpose: DirectoryList is a sequence class written to make walking
# through a directory tree very easy. Given a base class, it
# will generate a sequence of all the subdirectories.
# License: Released into the public domain by Neel Krishnaswami 15-Mar-1999
# Version: 0.1.0
# Warranty: None whatsoever, use at your own risk. :)
import os
_version = (0,1,0)
class DirectoryList:
"""DirectoryList -- a sequence class that represents the list of
subdirectories under a base directory. It's intended to make
stepping through a directory tree extremely easy.
Object creation:
foo = DirectoryList(base):
base is the path that is the root of the directory tree.
Ex: foo = DirectoryList('c:/Program Files/NTEmacs')
Methods:
A DirectoryList supports most of the standard sequence operations,
including slices. It is guaranteed that the elements will be in
ascii-betical order; this makes it easier to do things like pick
a range containing a set of subdirectories.
>>> for i in range(len(foo)):
... print foo[i]
...
c:\program files\ntemacs\lisp
c:\program files\ntemacs\lisp\calendar
c:\program files\ntemacs\lisp\emacs-lisp
c:\program files\ntemacs\lisp\emulation
c:\program files\ntemacs\lisp\gnus
c:\program files\ntemacs\lisp\international
c:\program files\ntemacs\lisp\language
c:\program files\ntemacs\lisp\mail
c:\program files\ntemacs\lisp\play
c:\program files\ntemacs\lisp\progmodes
c:\program files\ntemacs\lisp\term
c:\program files\ntemacs\lisp\textmodes
>>> for directory in foo[3:6]:
... print directory
...
c:\program files\ntemacs\lisp\emulation
c:\program files\ntemacs\lisp\gnus
c:\program files\ntemacs\lisp\international
The other methods of DirectoryList are:
o DirectoryList.index(path) -- returns the index of the first
element that matches the argument. It raises a ValueError if
no element of the directory list matches the path.
>>> foo.index('C:/Program Files/NTEmacs/lisp/gnus')
4
>>> foo.index('C:/Python')
Traceback (innermost last):
File "<stdin>", line 1, in ?
File "c:/windows/TEMP/python--3949155iIT", line 30, in index
ValueError: DirectoryList.index(path): path not in list
o DirectoryList.renew_subdirs() -- this recreates the directory list,
in case you have made changes to the directory hierarchy.
The DirectoryList class creates its list of subdirectories at
object creation, and keeps that. If you've made alterations to
the directory tree, you may want to invoke the renew_subdirs()
method to resync the object's internal list and the file system.
"""
def __init__(self, base):
self.base = os.path.normcase(os.path.normpath(base))
self.renew_subdirs()
def renew_subdirs(self):
"""DirectoryList.renew_subdirs() -- this recreates the directory
list, in case you have made changes to the directory hierarchy.
The DirectoryList class creates its list of subdirectories at
object creation, and keeps that. If you've made alterations to
the directory tree, you may want to invoke the renew_subdirs()
method to resync the object's internal list and the file system."""
self.subdirs = []
#
# I'd like to find a faster way of getting the directories
# than os.path.walk(), as long as I don't have to do any
# work. :)
os.path.walk(self.base,
lambda arg, dirname,
names, l=self.subdirs: l.append(dirname),
None
)
self.subdirs.sort()
def index(self, rawdir):
"""DirectoryList.index(path) -- returns the index of the first
element that matches the argument. It raises a ValueError if
no element of the directory list matches the path."""
dir = os.path.normcase(os.path.normpath(rawdir))
try:
i = self.subdirs.index(dir)
except:
raise ValueError, "DirectoryList.index(path): path not in list"
return i
def __cmp__(self, other):
if type(other) == type(self.subdirs):
return cmp(self.subdirs, other)
else:
return cmp(self.subdirs, other.subdirs)
def __getitem__(self, i):
return self.subdirs[i]
def __getslice__(self, i, j):
return self.subdirs[i:j]
def __len__(self):
return len(self.subdirs)
def __str__(self):
return 'DirectoryList:\n' + str(self.subdirs)
def __repr__(self):
return "DirectoryList(%s)" % repr(self.base)