如何在Python中将完全限定的类名映射到其类对象?

9
您可以像这样获取Python对象的完全限定类名(请参见此问题):
>>> import Queue
>>> q = Queue.PriorityQueue()
>>> def fullname(o):
    return o.__module__ + "." + o.__class__.__name__  
...   
>>> fullname(q)
'Queue.PriorityQueue'
>>> 

如何进行反向操作,即将一个完整限定类名(如'Queue.PriorityQueue')映射到其关联的类对象(Queue.PriorityQueue)?


我认为你做不到,因为如果我使用 from Queue import PriorityQueue,那么在我的程序中 Queue.PriorityQueue 不是一个类对象,只是 PriorityQueue - agf
一个很长的文本,但我认为这就是你需要的:[链接](http://blog.garlicsim.org/post/2958629526/address-tools-more-powerful-replacements-for-eval) - JBernardo
3个回答

11

您可以在Python 2.7中使用importlib模块:

from importlib import import_module

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

在旧版中,您可以使用__import__函数。它默认返回包导入的顶级(例如xml)。但是,如果您传递一个非空的fromlist,它将返回指定的模块:

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

感谢@eryksun,这正是我们需要的(我们正在使用Python 2.6)。 - Jim Ferrans

1

适用于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


0
在Python中,标识符并不是真正意义上用于这种情况的,但是通过使用sys.modules__import__,你可以实现你想要的功能。
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

示例使用
my_queue = get_by_qualified_name("Queue.Queue")()
my_queue.put("Hello World")
print my_queue.get() # prints "Hello World"

如果模块不作为__ALL__的一部分导入到包中,则此操作将失败。虽然可以修复此问题,但需要更加精细地使用__import__


如果您的字符串不是 module.attr1.attr2,而是 package1.package2.module.attr1.attr2,那么这也会失败。 - glglgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接