[Tutor] Advice on Python codes - A recursive function to output entire directory subkeys of Windows Registry

spir denis.spir at gmail.com
Thu Feb 6 13:02:39 CET 2014


On 02/05/2014 04:30 PM, Alan Ho wrote:
> Hi,
>
> I am a novice in Python, having attended a course few weeks ago and I'm working on my assignment now, and I encounter this issue when I was trying to print the entire Windows Registry (WR) sub-keys directories (trying that first with the below codes with adaptations from on-line research) and its value (later on).
>
> Kindly advise if any, as it has been taking me few days. What I need is a display on the std screen the entire directory of sub-keys (inserted into a list) in a WR key say, HKEY_CURRENT_FIG, and then I will write the contents into a text or CSV file.
> Thanks advance!
>
> Here are my codes,
>
> -----------------
> import winreg
>
> def traverse(root, key, list):
>      hKey = winreg.OpenKey(root, key)
>      try:
>          i = 0
>          while True:
>              strFullSubKey = ""
>              try:
>                  strSubKey = winreg.EnumKey(hKey, i)
>                  if (key != ""):
>                      strFullSubKey = key + "\\" + strSubKey
>                  else:
>                      strFullSubKey = strSubKey
>              except WindowsError:
>                  hKey.Close()
>                  return
>              traverse(root, strFullSubKey, list)
>              list.append(strFullSubKey)
>              i += 1
>
>      except  WindowsError:
>          hKey.Close()
>
> global list
> list = list()
> traverse (winreg.HKEY_CURRENT_CONFIG,"",list)
> print (list)
>
> -----------------

This is all right in my view, a good example of (forward) recursive traversal 
(like for a tree). Very functional programming (FP), in fact. However, even in 
FP, people often make up a more "intuitive" interface to their functions, and I 
guess this would be much more pythonic. If you did this, your program may look like:

def win_key ():
     def rec_keys (node, key, list):	# often called 'loop'
         # recursive func

     keys = list()
     rec_keys (winreg.HKEY_CURRENT_CONFIG, "", keys)
     return keys

keys = win_keys()
print(keys)

First look at the last lines: they form a simple, "intuitive", usage. They are 
just what the client of your service --making a list of win reg keys-- expects, 
right? To achieve this, you have to make the recursivity an internal quality of 
the service, an "implementation detail". Clinet, users, don't care how you do it 
internally, you could in fact do ot otherwise, and they (the clients) should not 
be forced to deal with tyour implementation requirements or choices.

The example above thus defines an *internal* recursive func, the FP equivalent 
of a loop (for thos reason often called 'loop' in FP code). With (such) 
recursive funcs, we must pass to the func a start or end case 
(root=winreg.HKEY_CURRENT_CONFIG), a current index (key=""), a temporary result 
(list=list). This is what users should not be forced to deal with.

Side-note: avoid using python built-in names like 'list'.

PS: I don't understand why there is an outer try...except. The only statement in 
there that may fail I guess is "traverse(root, strFullSubKey, list)", but this 
is a self-call (self-recursive), so possible failure are already caught in the 
inner try...except. What happens if you get rid of it, and why?
(I may be wrong, but I suspect the following: you first had WindowsError 
exceptions and to deal with them introduced the outer try...except; then, 
because of the self-call, you had to introduce the inner try...except; but in 
fact the latter is the only one you need, it catches all possible exception of 
the process, WindowsError's. Notice both try...except constructs catch 
WindowsError's. Again i may be wrong.)

d






More information about the Tutor mailing list