9

You can get the fully qualified class name of a Python object like this (see this question):

>>> import Queue
>>> q = Queue.PriorityQueue()
>>> def fullname(o):
    return o.__module__ + "." + o.__class__.__name__  
...   
>>> fullname(q)
'Queue.PriorityQueue'
>>> 

How do you do the inverse, ie, map a fully qualified class name like 'Queue.PriorityQueue' to its associated class object (Queue.PriorityQueue)?

Community
  • 1
  • 1
Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
  • I don't think you can, because if I `from Queue import PriorityQueue` then `Queue.PriorityQueue` isn't a class object in my program, it's just `PriorityQueue`. – agf Aug 28 '11 at 03:31
  • A long text but I think that's what you need: [Link](http://blog.garlicsim.org/post/2958629526/address-tools-more-powerful-replacements-for-eval) – JBernardo Aug 28 '11 at 03:39

3 Answers3

11

You can use importlib in 2.7:

from importlib import import_module

name = 'xml.etree.ElementTree.ElementTree'
parts = name.rsplit('.', 1)
ElementTree = getattr(import_module(parts[0]), parts[1])
tree = ElementTree()

In older versions you can use the __import__ function. It defaults to returning the top level of a package import (e.g. xml). However, if you pass it a non-empty fromlist, it returns the named module instead:

name = 'xml.etree.ElementTree.ElementTree'
parts = name.rsplit('.', 1)    
ElementTree = getattr(__import__(parts[0], fromlist=['']), parts[1])
tree = ElementTree()
Eryk Sun
  • 33,190
  • 5
  • 92
  • 111
1

For Python 2.6/2.7



    import sys
    def hasModule(moduleName):
        return moduleName in sys.modules

    def getModule(moduleName):
        if hasModule(moduleName):
            return sys.modules[moduleName]

    def loadModule(moduleName):
        if not hasModule(moduleName):
            return __import__(moduleName)
        return getModule(moduleName)

    def createInstance(fqcn, *args):
        paths = fqcn.split('.')
        moduleName = '.'.join(paths[:-1])
        className = paths[-1]
        module = loadModule(moduleName)
        if module is not None:
            return getattr(module, className)(*args)

    pq = "Queue.PriorityQueue"
    pqObj = createInstance(pq)
    pqObj.put(1)
    print pqObj.get() #1

Jim Ferrans
  • 30,582
  • 12
  • 56
  • 83
t w
  • 31
  • 6
0

Identifiers in Python aren't really meant to be used like this, but with sys.modules and __import__ you can achive what you want.

import sys

def get_by_qualified_name(name):
    parts = name.split(".")
    module_name = parts[0]
    attribute_names = parts[1:]

    if module_name not in sys.modules:
        __import__(module_name)

    result = sys.modules[module_name]

    for attribute_name in attribute_names:
        result = getattr(result, attribute_name)

    return result
Example Use
my_queue = get_by_qualified_name("Queue.Queue")()
my_queue.put("Hello World")
print my_queue.get() # prints "Hello World"

This will fail if the module is in a package which doesn't import it as part of __ALL__. This is possible to fix, but it requires more elaborate use of __import__.

Jeremy
  • 1
  • 85
  • 340
  • 366
  • This will also fail if your string doesn't mean `module.attr1.attr2`, but `package1.package2.module.attr1.attr2`. – glglgl Aug 28 '11 at 05:43