[Tutor] how to decypther which module function was imported from when from module import * is used

Michael P. Reilly arcege@speakeasy.net
Mon, 28 May 2001 14:35:01 -0400 (EDT)


Remco Gerlich wrote
> 
> On  0, Michael Schmitt <lgwb@home.com> wrote:
> > I am trying to read code that has several line off "from module import *"
> > and I want to know how as I trying to read though the code how I decipher
> > which module a function has been imported from when the fully-qualified name
> > is not used.
> 
> In general, you can't. That's the problem with 'from module import *', and
> one of the reasons why it's usually a bad idea.
> 
> There are some exceptions, like GUI toolkits - wxPython is usually used with
> 'from wxPython.wx import *' - but *its* objects have names like wxApp,
> wxFrame, wxDialog - you can tell.
> 
> I suppose you can make a small function to use in the interpreter, like
> 
> def find_object(modulenames, name):
>    modules = [__builtins__]+map(__import__, modulenames)
>    modules.reverse()
>    
>    for mod in modules:
>       if hasattr(mod, name):
>          return mod.__name__
>    return "Not found"
> 
> Now you can keep track of the imported modules and see where something would
> come from. If the program does from...import * on sys, os and string, you
> could do

Actually, you can look in the sys.modules structure without having to
"remember" much.  The "sys" module is a built-in C module so you don't
have to worry about it adding space by being imported.

def find_object(obj, modnames=None):
  import sys
  # if we supply an ordered list of module names
  if modnames:
    modules = []
    for name in modnames:
      if sys.modules.has_key(name):
        modules.append( (name, sys.modules[name]) )
  # otherwise get an unordered list of all modules imported
  else:
    modules = sys.modules.items()
  objnames = []
  for (modname, module) in modules.items():
    for (objname, modobj) in vars(module):
      if obj is modobj:
        objnames.append( '%s.%s' % (modname, objname) )
  return objnames  # return the list of module.object names

As you can see, the disadvantage of this is that, unless you give all the
module names you wish to search, a) it will search all loaded modules,
and b) it will not search in the order the modules were imported (but
that could be handled by keeping track of the order though the "imp"
or "imputil" modules).  But the advantage is that is checks for object
identity, not just name binding.

Python 2.1 also has a new module called "inspect" with a function called
"getmodule" which tries to deduce which module an object is defined in.

  -Arcege

-- 
+----------------------------------+-----------------------------------+
| Michael P. Reilly                | arcege@speakeasy.net              |