views:

45

answers:

3
>>> import_path('os.path.join')
<function join at 0x22d4050>

What is the simplest way to write import_path (in Python 2.6 and above)? Assume that the last component is always a callable in a module/package.

A: 

Try

def import_path(name):
  (mod,mem) = name.rsplit('.',1)
  m = __import__(mod, fromlist=[mem])
  return getattr(m, mem)

Works at least for

>>> import_path('os.walk')
<function walk at 0x7f23c24f8848>

and now

>>> import_path('os.path.join')
<function join at 0x7f7fc7728a28>
Geoff Reedy
Try it for `os.path.join` and let me know if it works. :-)
Sridhar Ratnakumar
ugh, __import__ semantics are dumb
Geoff Reedy
@sridhar fortunately, it's easy enough to work around, see my latest edit
Geoff Reedy
A: 

Apparently the following works:

>>> p = 'os.path.join'
>>> a, b = p.rsplit('.', 1)
>>> getattr(__import__(a, fromlist=True), b)
<function join at 0x7f8799865230>
Sridhar Ratnakumar
Am I not abusing the `fromlist` parameter?
Sridhar Ratnakumar
Yes, you are :)
Thomas Wouters
+2  A: 

This seems to be what you want:

def import_path(name):
    modname, _, attr = name.rpartition('.')
    if not modname:
        # name was just a single module name
        return __import__(attr)
    m = __import__(modname, fromlist=[attr]))
    return getattr(m, attr)

To make it work with Python 2.5 and earlier, where __import__ doesn't take keyword arguments, you will need to use:

m = __import__(modname, {}, globals(), [attr])
Thomas Wouters