【问题标题】:How do you map a fully qualified class name to its class object in Python?如何将完全限定的类名映射到 Python 中的类对象?
【发布时间】:2011-11-05 08:10:19
【问题描述】:

您可以像这样获取 Python 对象的完全限定类名(请参阅this question):

>>> 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
  • 很长的文字,但我认为这就是您需要的:Link

标签: python introspection


【解决方案1】:

您可以在 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)。
【解决方案2】:

对于 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

【讨论】:

    【解决方案3】:

    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,这也会失败。
    猜你喜欢
    • 2011-01-02
    • 2020-11-12
    • 2012-03-27
    • 2011-11-08
    • 2013-06-16
    • 2017-12-24
    • 2016-09-30
    • 1970-01-01
    • 2014-06-04
    相关资源
    最近更新 更多