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)?

2
  • 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. Commented Aug 28, 2011 at 3:31
  • A long text but I think that's what you need: Link Commented Aug 28, 2011 at 3:39

3 Answers 3

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()
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @eryksun, this is exactly what we needed (we're using Python 2.6).
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

Comments

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__.

1 Comment

This will also fail if your string doesn't mean module.attr1.attr2, but package1.package2.module.attr1.attr2.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.