[Tutor] Tutor Digest, Vol 33, Issue 64
Danny Yoo
dyoo at hkn.eecs.berkeley.edu
Thu Nov 16 20:51:13 CET 2006
> I have been fighting with this for a couple of days and am getting
> frustrated with it. I am trying to figure out a way to walk through the
> windows registry and to capture all nodes under the
> HKEY_CLASSES_ROOT\CLSID key and then put it into a list.
Ok, let's do this carefully. Let's first look at the source code, and
I'll make comments as we go along:
> def ListRegistryKeys(path):
> # if its empty do nothing
> if not path: return
> key=_winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, path)
> i=0
> name = []
> try:
> while 1:
> name.append(path + "\\" + _winreg.EnumKey(key, i))
> print name[-1]
> i += 1
> except WindowsError:
> pass
> _winreg.CloseKey( key)
> for item in name:
> ListRegistryKeys(item)
> return name
First, we have to say what ListRegisterKeys expects to take in and what we
expect for it to return. Here, it looks like it expects to take in a
path, and returns...? It looks like it's supposed to return a list of
names.
If that's true, take a very close look at any place where ListRegistryKeys
is being used, or where it is returning values back:
> # if its empty do nothing
> if not path: return
That's not quite right: it must return some list of things. Thankfully,
it's perfectly ok to return a list of no elements:
if not path: return []
Ok, let's look at another snippet:
> for item in name:
> ListRegistryKeys(item)
What's going on here are recursive calls. From the reasoning above, we
know that ListRegistryKeys() will give us back a list of names for that
item. We'd better not let those results just drop onto the floor. We
should collect them!
subnames = []
for item in name:
subnames.extend(ListRegistryKeys(item))
We collect all of the names of the inner registry keys in 'subnames'.
Finally, when we return the result of the whole thing, we must combine the
results of the recursive calls together with our initial set of names.
return name + subnames
Here's what the code looks like with all those changes, plus some variable
renaming and variable shifting.
##############################################################
def ListRegistryKeys(path):
"""ListRegistryKeys: given a path, returns a list of key names
underneath that path."""
if not path:
return []
names = []
key = _winreg.OpenKey(_winreg.HKEY_CLASSES_ROOT, path)
try:
i = 0
while 1:
names.append(path + "\\" + _winreg.EnumKey(key, i))
i += 1
except WindowsError:
pass
_winreg.CloseKey(key)
subnames = []
for item in names:
subnames.extend(ListRegistryKeys(item))
return names + subnames
##############################################################
You may want to read:
http://www.ibiblio.org/obp/thinkCSpy/chap04.html#auto8
... Unfortunately, the way that that book introduces recursive functions
is bad in the sense that it focuses way too much on IO, on printing things
rather than on manipulating values.
The meager example in the next chapter is not much better.
http://www.ibiblio.org/obp/thinkCSpy/chap05.html#auto4
Ugh. The factorial function is a sad way to introduce recursion because
it's irrelevant to most people.
If you have time, take a look at:
http://www.htdp.org/
In particular,
http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-13.html#node_sec_9.4
which isn't Python, but has a good approach to teaching useful recursion.
You can then bring that knowledge back into Python-space.
More information about the Tutor
mailing list