xray module

R

Robert Brewer

I finally cleaned up the code I've been using for a while now to grab
objects out of modules via dotted-package names (all this work to avoid
using exec! Sheesh!). Feel free to use it, abuse it, or comment on it. I
realize many of you already do this on your own--this is just sugar for
the newbies. I'm releasing/announcing it for three reasons:

1. The ego rush of authorship, :D
2. I continually hear people asking for similar (if not exact)
functionality, especially those coming from a Java/Tomcat background,
and
3. The name is cool. I spent a lot of time on it.

Here 'tis:


# xray.py
"""Load modules, classes, functions, and attributes by dotted package
names.

Usage:

desiredClass = xray.classes("myapp.strtools.alwayslowercase", str)
newInstance = desiredClass()

or

for f in startup_function_names:
func_object = xray.functions(f)
func_object()


Rationale:

I try to create systems that are configurable by deployers; mostly
becase I
hate it when an application forces me to use the database, filesystem,
communication protocol, algorithm, or operating system du jour.
Abstracting
these basic components of an application is its own study (look up the
Gang
of Four "Strategy" pattern for a start); this is often accomplished with
classes which share signatures, often via subclassing. However, the
deployer
then needs to specify the class they wish to use. This module gives them
the ability to specify that with a single string (for example, in a text
configuration file).

"""

import sys

def modules(modulePath):
"""Load a module and retrieve a reference to that module."""
try:
aMod = sys.modules[modulePath]
if aMod is None:
raise KeyError
except KeyError:
# The last [''] is important.
aMod = __import__(modulePath, globals(), locals(), [''])
sys.modules[modulePath] = aMod
return aMod

def attributes(fullAttributeName):
"""Load a module and retrieve an attribute of that module."""

# Parse out the path, module, and attribute
lastDot = fullAttributeName.rfind(u".")
attrName = fullAttributeName[lastDot + 1:]
modPath = fullAttributeName[:lastDot]

aMod = modules(modPath)
# Let an AttributeError propagate outward.
anAttr = getattr(aMod, attrName)

# Return a reference to the attribute.
return anAttr

def functions(fullFuncName):
"""Load a module and retrieve a function object."""

aFunc = attributes(fullFuncName)

# Assert that the function is a *callable* attribute.
if not callable(aFunc):
raise TypeError(u"'%s' is not callable." % fullFuncName)

# Return a reference to the function itself,
# not the results of the function.
return aFunc

def classes(fullClassName, parentClass=None):
"""Load a module and retrieve a class (NOT an instance).

If the parentClass is supplied, className must be of parentClass
or a subclass of parentClass (or None is returned).
"""
aClass = functions(fullClassName)

# Assert that the class is a subclass of parentClass.
if parentClass is not None:
if not issubclass(aClass, parentClass):
raise TypeError(u"'%s' is not a subclass of %s" %
(fullClassName, parentClass.__name__))

# Return a reference to the class itself, not an instantiated
object.
return aClass

# end xray.py


Robert Brewer
MIS
Amor Ministries
(e-mail address removed)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top