Revision 3 as of 2005-04-15 04:37:07

Clear message

I frequently want to find all the modules in some directory, with some property, and do something with them.

If you know how, please inform me. Here are some things I'm researching.

Finding the Things Inside a Module

   1 module.__dict__

Identifying Functions

   1 import types
   2 
   3 def is_it_a_function(obj):
   4     return isinstance(obj, types.FunctionType)

Finding Functions Within a Module

So, putting them together,...

   1 def functions_in_module(module)
   2     functions = []
   3     for obj in module.__dict__.values():
   4         if isinstance(obj, types.FunctionType):
   5             functions.append(obj)
   6     return functions

Finding Modules in a Directory

Is there a better way than just listing the contents of the directory, and taking those tiles that end with ".pyc" or ".py"..?

Importing the Modules

How do you do it dynamically, just given a filename?

Once you've imported it, how do you get a handle on it? (That is, how do you get it's dict?)

There seems to be [http://www.python.org/doc/current/lib/module-imp.html a module imp] that can be used to dynamically load a named module.

Playing with imp Module

Make a file "eraseme.py":

   1 print "Successfully imported!"

Then, at the python shell,

   1 >>> import imp
   2 >>> returned = imp.find_module("eraseme", ["."])
   3 >>> returned
   4 (<open file 'eraseme.py', mode 'U' at 0xb7f62220>, 'eraseme.py', ('.py', 'U', 1))
   5 >>>

The find_module line searches for "eraseme" in the current working directory (".").

The first two returned items are self-explanatory, but what about that tuple- ('.py', 'U', 1) ..?

The first (".py") is obviously the extension.

'U' means, "I opened the file in UniversalNewline mode." Basically, universal newline mode is like read ("r"), except that it interprets all newline forms the same way.

Finally, the 1 is a code that matches against imp.PY_SOURCE (1), imp.PY_COMPILED (2), or imp.C_EXTENSION (3). Basically, it's telling us that the .py file is a source file.

Once you have this stuff, it's easy to load:

   1 >>> eraseme = imp.load_module("eraseme", returned[0], returned[1], returned[2])
   2 successfully imported!
   3 >>> eraseme
   4 <module 'eraseme' from './eraseme.py'

Note that, you don't have to play by the rules. If you wanted to, you could have said:

   1 >>> module = imp.load_module("eggs", returned[0], "spam.py", returned[2])
   2 successfully imported!
   3 >>> module
   4 <module 'eggs' from 'spam.py'>
   5 >>> dir(module)
   6 ['__builtins__', '__doc__', '__file__', '__name__']
   7 >>> module.__name__
   8 'eggs'
   9 >>> module.__file__
  10 'spam.py'
  11 >>>

...even though the file's real name is "eggs.py".

Unable to edit the page? See the FrontPage for instructions.