class / module introspection?

7stud bbxx789_05ss at yahoo.com
Wed Apr 2 17:26:05 EDT 2008


On Apr 2, 1:27 pm, Brian Munroe <brian.e.mun... at gmail.com> wrote:
> On Apr 2, 12:07 pm, Brian Munroe <brian.e.mun... at gmail.com> wrote:
>
>
>
> > This gives me ['system1','system2'] - which I can then use __import__
> > on.
>
> Addendum, thanks Bruno!
>
> I also required the helper function (my_import) from the Python docs
>

You don't need that helper function, which is a little tricky to
follow:

If you have a module name as a string, you can use the builtin
function __import__ to import the module, e.g.

x = __import__("mymod")
x.myfunc()

Note that you have to assign the return value of __import__ to a
variable.  Thereafter you use the variable to access the module's
functions.

However, when you use __import__ with a package, it behaves in a
peculiar manner: it returns the top level package object.  For
example, if you write:

x = __import__("mypackage.subpack.myfuncs")


then x is a reference to mypackage--not mypackage.subpack.myfuncs.  In
order to execute a function in the module myfuncs, you need to write:

x.subpack.myfuncs.f().

Or, if you check the docs, you can make __import__ return the
rightmost module in the module string by writing:

x = __import__("mypackage.subpack.myfuncs", globals(), locals(),
["subpack.myfuncs"])

The last argument is what makes __import__ return a lower level module
in the package hierarchy.


To solve your problem, you can do something like the following:

Directory structure
-------------------

../mypackage
       __init__.py

       /system1
           __init__.py
           myfuncs.py

       /system2
           __init__.py
           myfuncs.py


system1/myfuncs.py
------------
def f():
    print "system1 here"


system2/myfuncs.py
-----------------
def f():
    print "system2 here"




import sys
import os

#Get all the file names contained in mypackage:
fnames = os.listdir("../mypackage")
print fnames

#Separate out the directory names(which are the sub packages):
os.chdir("../mypackage") #so abspath() below can construct full paths
package_dirs = []

for fname in fnames:
    abs_path = os.path.abspath(fname)  #need full path for isdir()
    print abs_path,

    if os.path.isdir(abs_path):
        print 'dir'
        package_dirs.append(fname)
    else:
        print 'file'

print package_dirs

sys.path.append("../") #directs python to search the specified
                       #dir for any modules that are imported

#Import the sub packages:
for dir in package_dirs:
    modname = "%s.%s.%s" % ("mypackage", dir, "myfuncs")
    modname_minus_toplevel_packname = "%s.%s" % (dir, "myfuncs")

    mod = __import__(modname, globals(), locals(),
[modname_minus_toplevel_packname])
    mod.f()



--output:--
['__init__.py', '__init__.pyc', 'system1', 'system2']
/Users/me/2testing/mypackage/__init__.py file
/Users/me/2testing/mypackage/__init__.pyc file
/Users/me/2testing/mypackage/system1 dir
/Users/me/2testing/mypackage/system2 dir
['system1', 'system2']
system1 here
system2 here






More information about the Python-list mailing list