[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Visitor: Walking Directories “++”


Laziness is the mother of many a framework. Armed with the portable search_all script
from Example 6-17, I was able to better pinpoint files to be edited every time I changed
the book examples tree content or structure. At least initially, in one window I ran
search_all to pick out suspicious files and edited each along the way by hand in another
window.


Pretty soon, though, this became tedious, too. Manually typing filenames into editor
commands is no fun, especially when the number of files to edit is large. Since I occa-
sionally have better things to do than manually start dozens of text editor sessions, I
started looking for a way to automatically run an editor on each suspicious file.


Unfortunately, search_all simply prints results to the screen. Although that text could
be intercepted with os.popen and parsed by another program, a more direct approach
that spawns edit sessions during the search may be simpler. That would require major
changes to the tree search script as currently coded, though, and make it useful for just
one specific purpose. At this point, three thoughts came to mind:


Redundancy
After writing a few directory walking utilities, it became clear that I was rewriting
the same sort of code over and over again. Traversals could be even further sim-
plified by wrapping common details for reuse. Although the os.walk tool avoids
having to write recursive functions, its model tends to foster redundant operations
and code (e.g., directory name joins, tracing prints).


Extensibility
Past experience informed me that it would be better in the long run to add features
to a general directory searcher as external components, rather than changing the
original script itself. Because editing files was just one possible extension (what
about automating text replacements, too?), a more general, customizable, and re-
usable approach seemed the way to go. Although os.walk is straightforward to use,
its nested loop-based structure doesn’t quite lend itself to customization the way
a class can.


Encapsulation
Based on past experience, I also knew that it’s a generally good idea to insulate
programs from implementation details as much as possible. While os.walk hides
the details of recursive traversal, it still imposes a very specific interface on its cli-
ents, which is prone to change over time. Indeed it has—as I’ll explain further at
the end of this section, one of Python’s tree walkers was removed altogether in 3.X,
instantly breaking code that relied upon it. It would be better to hide such de-
pendencies behind a more neutral interface, so that clients won’t break as our needs
change.


Of course, if you’ve studied Python in any depth, you know that all these goals point
to using an object-oriented framework for traversals and searching. Example 6-18 is a


330 | Chapter 6: Complete System Programs

Free download pdf